为什么不在频道上发送并阻止执行?如何使这个星座工作,以便我可以向MoneyDive()
发送信号并继续执行?
package main
import (
"fmt"
)
type Quack func(ch chan bool)
type DagobertDuck struct {
quack Quack
}
func (self *DagobertDuck) MoneyDive() {
ch := make(chan bool)
self.quack(ch)
b := <-ch
if b {
fmt.Println("true")
} else {
fmt.Println("false")
}
}
func mockQuack(ch chan bool) {
fmt.Println("mockQuack start")
ch <- true
fmt.Println("mockQuack done")
}
func main() {
dd := DagobertDuck{quack: mockQuack}
dd.MoneyDive()
}
答案 0 :(得分:3)
因为你有一个无缓冲的频道,你只能在没有阻止的情况下在无缓冲的频道上发送一个值,如果有另一个goroutine已准备好接收它。
由于你只有1个goroutine,它会被阻止。解决方案很简单:在新的goroutine中启动Quack.quack()
方法:
go self.quack(ch)
然后输出(在Go Playground上尝试):
mockQuack start
mockQuack done
true
另一个选择是不启动新的goroutine但是创建一个缓冲的通道,因此它可以保存一些值,而没有任何接收器可以从它接收:
ch := make(chan bool, 1) // buffered channel, buffer for 1 value
这创建了一个能够&#34;存储&#34;没有任何接收器准备接收它的一个值。除非首先从它接收到值(或接收器准备从其接收值),否则通道上的第二次发送也将阻塞。
在Go Playground上尝试此缓冲频道版本。
规范中的相关部分:Send statements:
在通信开始之前评估通道和值表达式。 通信阻止,直到发送可以继续。如果接收器准备就绪,则可以继续在无缓冲信道上发送。如果缓冲区中有空间,则缓冲信道上的发送可以继续。通过导致run-time panic继续在封闭频道上发送。 nil 频道上的发送会永久阻止。
备注:强>
根据收到的值,您可以打印true
或false
。这可以使用一行完成,不需要if
语句:
fmt.Println(b)
您甚至可以删除b
局部变量,并立即打印收到的值:
fmt.Println(<-ch)
此外,我假设您使用了频道,因为您想要使用这些频道,但在您的情况下,mockQuack()
只需返回bool
值,而无需使用频道。