How can I make the RemoveDead function accept other slices of interfaces (or maybe even slices of struct pointers) that implement Liver with little impact on performance?
It seems to me that the function would have to take an interface{} as argument and do runtime conversions, but I'm not sure how to do the conversions. I would also guess that doing x.(Liver) is a lot slower than Liver(x), because the latter is a compile time conversion.
Is the best solution to copy-paste the function and change the argument and return type in each copy? Only three or four copies would be needed, but it would still feel like a very clumsy solution.
type Updater interface {
Liver
Update() bool
}
type Liver interface {
Alive() bool
}
func RemoveDead(all []Updater) []Updater {
for i := len(all) - 1; i >= 0; i-- {
if Liver(all[i]).Alive() == false {
all[i] = all[len(all)-1]
all = all[:len(all)-1]
}
}
return all
}
As you mentioned, a slice of type []Updater cannot be turned to a []Liver with a simple type assertion; their type are not interfaces, but slices of interfaces. For the same reason is it not possible to pass a []Updater to a function wanting an []interface{} as parameter.
However, you can do what you desire using the reflect package. Reflection is useful but will come at a cost on performance. If you consider the cost to high, then you will probably have to use the copy-paste solution.
The code below can surely be improved, but it shows how to solve the problem with reflection, and it might be useful when making a benchmark. Currently it regards any even U value as Alive:
package main
import (
"fmt"
"reflect"
)
type Updater interface {
Alive() bool
Update() bool
}
type Liver interface {
Alive() bool
}
type U int
func (u U) Alive() bool { return u % 2 == 0 }
func RemoveDead(all interface{}) interface{} {
v := reflect.ValueOf(all)
if v.Kind() != reflect.Slice {
panic("RemoveDead requires a slice")
}
for i := v.Len() - 1; i >= 0; i-- {
l := v.Index(i)
if l.Interface().(Liver).Alive() == false {
l.Set(v.Index(v.Len()-1))
v = v.Slice(0, v.Len()-1)
}
}
return v.Interface()
}
func main() {
u := []U{1,4,7,2,12}
fmt.Println("Before: ", u)
u = RemoveDead(u).([]U)
fmt.Println("After: ", u)
}
Output:
Before: [1 4 7 2 12]
After: [2 4 12]
Playground
You could define third interface:
type UpdaterLiver interface {
Updater
Liver
}
then change definition of RemoveDead to be
func RemoveDead(all []UpdaterLiver) []UpdaterLiver
Related
If I try a file like this:
package main
import "time"
type Alpha time.Time
func main() {
o := Alpha.Now()
n := o.Unix()
println(n)
}
I get this result:
Alpha.Now undefined (type Alpha has no method Now)
However it works with other languages. For example PHP:
<?php
class Alpha extends DateTime {}
$o = new Alpha;
$n = $o->getTimestamp();
var_dump($n);
It is possible with Go, to create a new type that has access to the methods of
another type?
First of all, time.Now() is just a package-level function, not a method of any type. Thus, the proper way to invoke it would look like smth := time.Time(), not smth := time.Time.Now().
We can take a closer look at the function. It's defined in package time and currently implemented as follows:
func Now() Time {
sec, nsec, mono := now()
mono -= startNano
sec += unixToInternal - minWall
if uint64(sec)>>33 != 0 {
return Time{uint64(nsec), sec + minWall, Local}
}
return Time{hasMonotonic | uint64(sec)<<nsecShift | uint64(nsec), mono, Local}
}
As you can see, it returns an object of type time.Time. Which then can be used for the consequent .Unix() method call:
func (t Time) Unix() int64 {
return t.unixSec()
}
In case of Unix() it's a true method with the receiver of type time.Time.
For the extension part of your question, you can use the following trick:
package main
import "time"
type Alpha struct {
time.Time
}
func main() {
o := time.Now()
a := Alpha { o }
n := a.Unix()
println(n)
}
Go doesn't provide any model of inheritance. However, its composition capabilities are very powerful. The code from the snippet above basically creates a new struct type Alpha with an anonymous attribute of type time.Time. However, due to the fact that the explicit name of this attribute is skipped, we can access methods of a contained time.Time instance right through the parent structure. The technique is called Embedding.
Can I create a generator in Swift?
With iterator, I need store intermediate results, for example:
struct Countdown: IteratorProtocol, Sequence {
private var value = 0
init(start: Int) {
self.value = start
}
mutating func next() -> Int? {
let nextNumber = value - 1
if nextNumber < 0 {
return nil
}
value -= 1
return nextNumber
}
}
for i in Countdown(start: 3) {
print(i)
} // print 1 2 3
In this example, I need store the value.
In my situation, I want to use generator instead of iterator, because I don't want store the intermediate results of my sequence in each next.
Understanding how generators work (and why they are less important in swift) is at first difficult coming from Python.
Up to Swift v2.1 there was a protocol called GeneratorType. This was renamed to IteratorProtocol in Swift v3.0+. You can conform to this protocol to make your own objects that do just-in-time computations similar to what can be done in Python.
More information can be found in the Apple Documentation: IteratorProtocol
A simple example from IteratorProtocol page:
struct CountdownIterator: IteratorProtocol {
let countdown: Countdown
var times = 0
init(_ countdown: Countdown) {
self.countdown = countdown
}
mutating func next() -> Int? {
let nextNumber = countdown.start - times
guard nextNumber > 0
else { return nil }
times += 1
return nextNumber
}
}
let threeTwoOne = Countdown(start: 3)
for count in threeTwoOne {
print("\(count)...")
}
// Prints "3..."
// Prints "2..."
// Prints "1..."
However, you need to think about why you are using a generator:
Swift automatically does something "called copy on write." This means that many of the cases that use a Python generator to avoid the large copying cost of collections of objects (arrays, lists, dictionaries, etc) are unnecessary in Swift. You get this for free by using one of the types that use copy on write.
Which value types in Swift supports copy-on-write?
It is also possible to use a wrapper to force almost any object to be copy on write, even if it is not part of a collection:
How can I make a container with copy-on-write semantics?
The optimizations in swift usually mean that you do not not have to write generators. If you really do need to (usually because of data heavy, scientific calculations) it is possible as above.
Based on the code you provided and the little bit knowledge of generators that I do have, you can do something like
struct Countdown {
private var _start = 0
private var _value = 0
init(value: Int) {
_value = value
}
mutating func getNext() -> Int? {
let current = _start
_start += 1
if current <= _value {
return current
} else {
return nil
}
}
}
and then wherever you want to use it, you can do something like
var counter = Countdown(value: 5)
while let value = counter.getNext() {
print(value)
}
Walter provides a lot of good information, and generally you shouldn't be doing this in Swift, but even if you wanted an Iterator, the right way to do it is with composition, not by building your own. Swift has a lot of existing sequences that can be composed to create what you want without maintaining your own state. So in your example, you'd differ to a range's iterator:
struct Countdown: Sequence {
private var value = 0
init(start: Int) {
self.value = start
}
func makeIterator() -> AnyIterator<Int> {
return AnyIterator((0..<value).reversed().makeIterator())
}
}
for i in Countdown(start: 3) {
print(i)
} // print 1 2 3
Something has to keep the state; that's the nature of these kinds of functions (even in a world with coroutines). It's fine not to maintain it directly; just delegate to a more primitive type. Swift has a couple of dozen built-in Iterators you can use to build most things you likely need, and any iterator can be lifted to an AnyIterator to hide the implementation details. If you have something custom enough that it really requires a next(), then yes, storing the state is your problem. Something has to do it. But I've found this all to be extremely rare, and often suggests over-design when it comes up.
I have a solution similar to above, but with a slightly more "yield-y" feeling to it.
struct Countdown
{
static func generator(withStart: Int) -> () -> Int?
{
var start = withStart + 1
return {
start = start - 1
return start > 0 ? start : nil
}
}
}
let countdown = Countdown.generator(withStart: 5)
while let i = countdown()
{
print ("\(i)")
}
I have this function in swift
func *<T1:Sequence, T2:Sequence>(lhs: T1,rhs : T2) ->
[(T1.Iterator.Element,T2.Iterator.Element)]
{
let product = lhs.flatMap({ x in rhs.lazy.map{y in (x,y)}})
return product
}
I want to make it evaluate lazy. I know i can use lhs.lazy.flatmap but what should the return type be? Or is there a better or other way to do something like this?
You can create a type-erased sequence, which forward its operations to an underlying base
sequence having the same Element type, hiding the specifics of the
underlying sequence:
func *<T1:Sequence, T2:Sequence>(lhs: T1,rhs : T2) -> AnySequence<(T1.Iterator.Element,T2.Iterator.Element)>
{
return AnySequence (
lhs.lazy.flatMap { x in rhs.lazy.map { y in (x,y) }}
)
}
Then your code is independent of the actual implementation of lazy.flatMap and its exact return type (which may even change with
newer Swift releases).
Thanks to Alexander I came up with
func *<T1:Sequence, T2:Sequence>(lhs: T1,rhs : T2) ->
LazySequence<FlattenSequence<LazyMapSequence<T1,
LazyMapSequence<T2, (T1.Iterator.Element, T2.Iterator.Element)>>>> {
let product = lhs.lazy.flatMap({ x in rhs.lazy.map{y in (x,y)}})
print(type(of:product))
return product
}
That works but somehow that return type seems a bit to much for my taste.
I am a beginner in Swift so some things aren't quite clear to me yet. I hope somebody would explain this to me:
// Creating Type Properties and Type Methods
class BankAccount {
// stored properties
let accountNumber: Int
let routingCode = 12345678
var balance: Double
class var interestRate: Float {
return 2.0
}
init(num: Int, initialBalance: Double) {
accountNumber = num
balance = initialBalance
}
func deposit(amount: Double) {
balance += amount
}
func withdraw(amount: Double) -> Bool {
if balance > amount {
balance -= amount
return true
} else {
println("Insufficient funds")
return false
}
}
class func example() {
// Type methods CANNOT access instance data
println("Interest rate is \(interestRate)")
}
}
var firstAccount = BankAccount(num: 11221122, initialBalance: 1000.0)
var secondAccount = BankAccount(num: 22113322, initialBalance: 4543.54)
BankAccount.interestRate
firstAccount.deposit(520)
So this is the code. I am wondering why deposit() doesn't have a return arrow and return keyword and withdraw() does. When do I use a return arrow, in what situations, is there a rule or something? I don't understand.
In addition...
Everyone is so kind with your answers, it is getting clearer to me now.
In beginning of this tutorial there is practice code for functions
// Function that return values
func myFunction() -> String {
return “Hello”
}
I imagine this return value is not needed here but in tutorial they wanted to show us that it exists, am I right?
Furthermore, can I make a "mistake" and use return arrow and value in my deposit function somehow? I tried with this:
func deposit(amount : Double) -> Double {
return balance += amount
}
... but it generated error.
I saw advanced coding in my last firm, they were creating online shop with many custom and cool features and all code was full of return arrows. That confused me and I thought that it is a default for making methods/functions in OOP.
Additional question!
I wanted to play with functions so I want to create a function transferFunds() which transfers money from one account to another. I made function like this
func transferFunds(firstAcc : Int, secondAcc : Int, funds : Double) {
// magic part
if firstAcc == firstAccount.accountNumber {
firstAccount.balance -= funds
} else {
println("Invalid account number! Try again.")
}
if secondAcc == secondAccount.accountNumber {
secondAccount.balance += funds
} else {
println("Invalid account number! Try again.")
}
}
This is a simple code that came to my mind but I know it is maybe even stupid. I know there should be a code that check if there is enough funds in first account from which I am taking money, but okay... Lets play with this.
I want to specify accountNumbers or something else in parameters within function transferFunds() and I want to search through all objects/clients in my imaginary bank which use class BankAccount in order to find one and then transfer money. I don't know if I described my problem correctly but I hope you understand what I want to do. Can somebody help me, please?
So in Swift, a function that has no arrow has a return type of Void:
func funcWithNoReturnType() {
//I don't return anything, but I still can return to jump out of the function
}
This could be rewritten as:
func funcWithNoReturnType() -> Void {
//I don't return anything, but I still can return to jump out of the function
}
so in your case...
func deposit(amount : Double) {
balance += amount
}
your method deposit takes a single parameter of Type Double and this returns nothing, which is exactly why you do not see a return statement in your method declaration. This method is simply adding, or depositing more money into your account, where no return statement is needed.
However, onto your withdraw method:
func withdraw(amount : Double) -> Bool {
if balance > amount {
balance -= amount
return true
} else {
println("Insufficient funds")
return false
}
}
This method takes a single parameter of Type Double, and returns a Boolean. In regard to your withdraw method, if your balance is less than the amount you're trying to withdraw (amount), then that's not possible, which is why it returns false, but if you do have enough money in your account, it gracefully withdraws the money, and returns true, to act as if the operation was successful.
I hope this clears up a little bit of what you were confused on.
Welcome to programming! Good questions, stick with it and you'll do well.
The functions that have a return value are providing the calling code with information. For example, for the deposit function, there is the expectation that nothing unusual will happen, so it's not bothering to return anything that could be checked by the caller.
In the withdrawal function, it's possible that the amount to be withdrawn could be greater than the balance available. If this is the case, the function will return false. The calling function could check that value and notify the user that they're attempting to withdraw more than is available. Otoh, if a value of true is returned, then the program will deduct that amount from the balance and presumably provide the customer with the funds requested.
Check out Function Parameters and Return Values in the Swift docs:
Functions are not required to define a return type. Here’s a version of the sayHello function, called sayGoodbye, which prints its own String value rather than returning it:
func sayGoodbye(personName: String) {
println("Goodbye, \(personName)!")
}
sayGoodbye("Dave")
// prints "Goodbye, Dave!"
Because it does not need to return a value, the function’s definition does not include the return arrow (->) or a return type.
In your example, deposit(_:) doesn't return anything, it just modifies an instance variable. This is typical of functions which will always succeed.
withdraw(:_), on the other hand, might fail (due to insufficient funds), so it returns a Bool indicating whether it worked or not.
This question can be referred as a language-agnostic one, so be my answer to you.
A method is a code block that contains a series of statements. Methods can return a value to the caller, but doesn't have to do so. It is the decision of you as the developer. Method that returns a value to the caller will consist the keyword: "return", and a value type declared in the method signature.
I would mention the Command Query Separation (CQS) principle coined by Bertrand Meyer. Martin Fowler rephrased: The fundamental idea is that we should divide an object's methods into two sharply separated categories:
Queries: Return a result and do not change the observable state of
the system (are free of side effects). Mark Seemann said queries do not mutate observable state. They are idempotent and safe to invoke.
Commands: Change the state of a system but do not return a value. You can, and it is safe to invoke queries from commands, but not vice versa.
Source: https://thenucleargeeks.com/2019/05/08/functions-in-swift/
In swift a function is defined by “func” keyword. When a function is declared based on requirement it may take one or more parameter, process it and return the valueFunction with no parameters and no return value.
Function with no parameter and no return type.
Syntax:
func function_name() {
--
}
func addTwoNumbers() {
let a = 1
let b = 2
let c = a+b
print(c) // 3
}
addTwoNumbers()
Function with no parameter and return type
Syntax:
func function_name() -> Data Type {
--
return some values
}
func addTwoNumbers()->Int {
let a = 1
let b = 2
let c = a+b
return c
}
let sum = addTwoNumbers()
print(sum) // 3
Function with parameter and return type
Syntax:
func function_name(arguments parameter_name: Data Type) -> Data Type {
------
return some values
}
func addTwoNumbers(arg param: Int)->Int {
let a = param
let b = 2
let c = a+b
return c
}
let sum = addTwoNumbers(arg: 4)
print(sum) // 6
Alternately you can skip the arg and directly pass the value to the function.
func addTwoNumbers(param: Int)->Int {
let a = param
let b = 2
let c = a+b
return c
}
let sum = addTwoNumbers(param: 4)
print(sum) // 6
Function with parameter and no return type
Syntax:
func function_name(arguments parameter_name: Data Type) {
----
return some values
}
func addTwoNumbers(arg param: Int){
let a = param
let b = 2
let c = a+b
print(c) //6
}
addTwoNumbers(arg: 4)
I have a code that I need to run exactly n times in Swift. What is the shortest possible syntax for that?
I am currently using the for loop but it is a lot of typing.
for i in 0..<n { /* do something */ }
Is there a shorter/nicer way for running same code n times in Swift?
Speaking of syntax, you might define your own shortest syntax:
extension Int {
func times(_ f: () -> ()) {
if self > 0 {
for _ in 0..<self {
f()
}
}
}
func times(_ f: #autoclosure () -> ()) {
if self > 0 {
for _ in 0..<self {
f()
}
}
}
}
var s = "a"
3.times {
s.append(Character("b"))
}
s // "abbb"
var d = 3.0
5.times(d += 1.0)
d // 8.0
Sticking with a for loop - you could extend Int to conform to SequenceType to be able to write:
for i in 5 { /* Repeated five times */ }
To make Int conform to SequenceType you'll could do the following:
extension Int : SequenceType {
public func generate() -> RangeGenerator<Int> {
return (0..<self).generate()
}
}
You have several ways of doing that:
Using for loops:
for i in 1...n { `/*code*/` }
for i = 0 ; i < n ; i++ { `/*code*/` }
for i in n { `/*code*/` }
using while loops:
var i = 0
while (i < n) {
`/*code*/`
` i++`
}
var i = 0
repeat {
` /*code*/`
`i++`
} while(i <= n)
for _ in 1...5 {
//action will be taken 5 times.
}
you could use functional programming on a range instead of a loop, for shorter and "nicer" syntax for example
(0..<n).forEach{print("Index: \($0)")}
Other answers mention defining your own syntax for that. So - that can be fine for a tiny personal project, or as a learning experience. But defining your own syntax for something so trivial and basic in a large project would be maintenance and readability hell.
You could do something like this:
10⨉{ print("loop") }
Using a custom operator and an extension on Int:
infix operator ⨉ // multiplication sign, not lowercase 'x'
extension Int {
static func ⨉( count:Int, block: () ->Void ) {
(0..<count).forEach { _ in block() }
}
}
ABakerSmith's answer updated for Swift 4:
extension Int: Sequence {
public func makeIterator() -> CountableRange<Int>.Iterator {
return (0..<self).makeIterator()
}
}
Use:
for i in 5 {
//Performed 5 times
}
Shorter and (I think) clearer:
for i in 1...n { } // note: this will fail if n < 1
or
for i in n { }
In Swift, what you have is the shortest syntax for performing a loop operation.
Swift provides two kinds of loop that perform a set of statements a
certain number of times:
The for-in loop performs a set of statements for each item in a
sequence.
The for loop performs a set of statements until a specific
condition is met.
If you want to run it infinite times, well try using a while.
There are a lot of answers here, highlighting just how creative you can be, with Swift.
I needed an array so I did this
extension Int {
func of<T>(iteration: (Int) -> T) -> [T] {
var collection = [T]()
for i in 0..<self {
collection.append(iteration(i))
}
return collection
}
}
fun strings() -> [String] {
return 4.of { "\($0) teletubby" }
}
for-loops are a common way to repeat code. Here is an example of using a for-loop to hide six outlets, versus writing the same code for six outlets. Plus if you make another outlet all you have to do is add it to the array.
let array = [outLet0, outlet1, outlet2, outLet3, outLet4, outLet5]
for outlet in array {
outlet.hidden = true
}
Versus writing it like this:
outlet0.hidden = true
outlet1.hidden = true
outlet2.hidden = true
outlet3.hidden = true
outlet4.hidden = true
outlet5.hidden = true
ONLY 5 CHARACTERS (not including n or code)
r(){}
If you're just testing things and need a REALLY short line, try this. Emphasis on using this for testing, not in production, because no one will know what is going on without documentation.
define this somewhere globally
func r(_ n : UInt, _ c: #escaping () -> Void) { for _ in 0..<n { c() } }
call this when you want to run it
r(5) { /*code*/ }
Swift is so awesome, just write your own function or extension and you got it ;) 100 of options there, everyone can do it its own way just look at those answers here.
Or better, write it as you already do, as is common when apps are build in team, as everyone would do it differently anyway and all projects need those extension to be written again or own libs to have and maintain just for stupid thing, that you can write just by some standard way, as you already did with your for loop.
The only loop shorter than that is an infinite while loop:
while (true) {
}
But you would still have to increase a counter and check it in the loop to break the loop, and in the end it wouldn't be shorter.