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 |
Channels in Swift can be buffered or unbuffered
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
!
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:
|
|
|
|
|
|
|
|
|
|
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
)
Example | ||
---|---|---|
|
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")
} |
|
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) |
|
let a = Channel<Bool>()
await select {
receive(a)
none {
print("Default case!")
}
} |
a := make(chan bool)
select {
case <-a:
default:
fmt.Println("Default case!")
} |