Skip to content

Latest commit

 

History

History
294 lines (212 loc) · 3.43 KB

GolangVsSwift.md

File metadata and controls

294 lines (212 loc) · 3.43 KB

Un-buffered Channels

Swift

Go

let msg = Channel<String>()
let done = Channel<Bool>()

Task {
    for await m in msg {
        print(m)
    }
    print("closed")
    await done <- true
}

await msg <- "hi"
msg.close()
await <-done
msg := make(chan string)
done := make(chan bool)

go func() {
    for m := range msg {
        fmt.Println(m)
    }
    fmt.Println("closed")
    done <- true
}()

msg <- "hi"
close(msg)
<-done

Buffered Channels

Channels in Swift can be buffered or unbuffered

Swift

Go

let count = Channel<Int>(capacity: 100)

for i in (0..<100) {
    await count <- i
}
count.close()


let sum = await count.reduce(0) { sum, next in
    sum + next
}
print(sum)
count := make(chan int, 100)

for i := 0; i < 100; i++ {
    count <- i
}
close(count)

sum := 0
for v := range count {
    sum += v
}
fmt.Println(sum)

Also map, reduce, etc work on channels in Swift too thanks to Sequence!

Select

Swift has reserve words for case and default and the operator support is not flexible enough to support inline channel operations in the select statement. So instead they are implemented as follows:

Swift

Go

receive(c)

case <-c:

receive(c) { v in ... }

case v := <-c: ...

send("foo", to: c)

case c <- "foo":

send("foo", to: c) { ... }

case c <- "foo": ...

none { ... }

default: ...

Gotcha: You cannot return from none to break an outer loop in Swift since it's inside a closure. To break a loop surrounding a select, you must explicitly set some control variable (ex: while !done and done = true)

Examples

Example

Swift

Go

chan receive

let a = Channel<String>(capacity: 1)
await a <- "foo"

await select {
    receive(a) { av in
        print(av!)
    }
    none {
        print("Not called")
    }
}
a := make(chan string, 1)
a <- "foo"

select {
case av := <-a:
    fmt.Println(av)

default:
    fmt.Println("Not called")

}

chan send

let a = Channel<String>(capacity: 1)

await select {
    send("foo", to: a)
    none {
        print("Not called")
    }
}
print(await <-a)
a := make(chan string, 1)

select {
case a <- "foo":
default:
    fmt.Println("Not called")
}

fmt.Println(<-a)

default

let a = Channel<Bool>()

await select {
    receive(a)
    none {
        print("Default case!")
    }
}
a := make(chan bool)

select {
case <-a:
default:
    fmt.Println("Default case!")

}