在下面的代码中:
package main
import (
"fmt"
"time"
)
func asChan(vs ...int) <-chan int {
c := make(chan int)
go func() {
for _, v := range vs {
c <- v
time.Sleep(2 * time.Second)
}
close(c)
}()
return c
}
func merge(a, b <-chan int) <-chan int {
c := make(chan int)
go func() {
for {
select {
case v := <-a:
c <- v
case v := <-b:
c <- v
}
}
}()
return c
}
func main() {
a := asChan(1, 3, 5, 7)
b := asChan(2, 4, 6, 8)
c := merge(a, b)
for value := range c {
fmt.Println(value)
}
}
下面是
v
的零值关闭 channel 后收到a
.但我的理解是,
case v := <-a:
中的这行代码(merge()
)函数应该阻塞输入,因为 channel ( a
)已关闭编辑:
代码更改后,
main()
不退出:func merge(a, b <-chan int) chan int {
c := make(chan int)
go func() {
defer close(c)
for a != nil || b != nil { // while atleast one channel is open
select {
case v, ok := <-a:
sendOnChannel(a, c, v, ok)
case v, ok := <-b:
sendOnChannel(b, c, v, ok)
}
}
}()
return c
}
func sendOnChannel(sourceChan <-chan int, targetChan chan int, v int, channelOpen bool) {
if !channelOpen {
// The channel is closed. Set channel variable
// to nil to disable this select / case.
sourceChan = nil
} else {
targetChan <- v
}
}
输出:
$ bin/cs61a
1
2
3
4
5
6
7
8
如何
a
在这行代码中生成零(case v := <-a
)?
最佳答案
A receive operation on a closed channel can always proceed immediately, yielding the element type's zero value after any previously sent values have been received.
我不知道语言设计者为什么选择这种设计,但它在实践中很有用。
使用二值接收语句来检测 channel 何时因为 channel 关闭而产生零值。
v, ok := <-a
if !ok {
// channel closed
}
使用以下代码实现合并:
func merge(a, b <-chan int) <-chan int {
c := make(chan int)
go func() {
defer close(c)
// While we have at least one channel ...
for a != nil || b != nil {
select {
case v, ok := <-a:
if ok {
c <- v
} else {
// The channel is closed. Set channel variable
// to nil to disable this select / case.
a = nil
}
case v, ok := <-b:
if ok {
c <- v
} else {
b = nil
}
}
}
}()
return c
}
Run it on the playground .
关于go - 封闭 channel 发送值为零吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61706675/