为什么频道没有成为结构的成员
why channel is not receiving being member of struct
代码:https://play.golang.org/p/Oh3oTa7GIPX
type a struct {
c chan bool
}
func (a *a) do() {
a.c <- true
}
type b struct {
c chan bool
a a
}
func main() {
b := b{
c: make(chan bool),
a: a{c: make(chan bool)},
}
go b.s()
b.c <- true
// below is to stay main gorutine alive
done := make(chan bool)
go func() {
time.Sleep(10 * time.Second)
done <- true
}()
for {
select {
case <-done:
fmt.Println("Done!")
return
}
}
}
func (b *b) s() {
for {
select {
case <-b.c:
fmt.Println("b c")
b.a.do()
case <-b.a.c:
fmt.Println("b a c")
}
}
}
上面的实际输出是
b c
Done!
预期输出:
b c
b a c
Done !
我不明白为什么它不打印 b a c
?
代码是不言自明的,如果还需要更多细节请询问
您的 main
goroutine 在 b.c
上发送一个值,然后等待:
b.c <- true
您从 main 启动的 goroutine:
go b.s()
这是从 b.c
收到的,也是从 b.a.c
收到的:
func (b *b) s() {
for {
select {
case <-b.c:
fmt.Println("b c")
b.a.do()
case <-b.a.c:
fmt.Println("b a c")
}
}
}
如果从 b.c
收到一个值,这个 goroutine 会尝试在 b.a.c
上发送(在 a.do()
方法中),而你期望这个 same goroutine 从 b.a.c
接收。但是由于 b.a.c
是无缓冲的,发送将阻塞,因此它永远不会到达 b.s()
中的下一次迭代,它可以/将从 b.a.c
.
接收
如果一个通道没有缓冲,只有当有另一个 goroutine 准备好从它接收时,它的发送才能继续。
如果您使 b.a.c
通道缓冲,发送可以在不阻塞的情况下继续进行,因此在下一次迭代中可以接收它:
a: a{c: make(chan bool, 1)}
通过此更改,您将获得预期的输出。在 Go Playground.
上试试
代码:https://play.golang.org/p/Oh3oTa7GIPX
type a struct {
c chan bool
}
func (a *a) do() {
a.c <- true
}
type b struct {
c chan bool
a a
}
func main() {
b := b{
c: make(chan bool),
a: a{c: make(chan bool)},
}
go b.s()
b.c <- true
// below is to stay main gorutine alive
done := make(chan bool)
go func() {
time.Sleep(10 * time.Second)
done <- true
}()
for {
select {
case <-done:
fmt.Println("Done!")
return
}
}
}
func (b *b) s() {
for {
select {
case <-b.c:
fmt.Println("b c")
b.a.do()
case <-b.a.c:
fmt.Println("b a c")
}
}
}
上面的实际输出是
b c
Done!
预期输出:
b c
b a c
Done !
我不明白为什么它不打印 b a c
?
代码是不言自明的,如果还需要更多细节请询问
您的 main
goroutine 在 b.c
上发送一个值,然后等待:
b.c <- true
您从 main 启动的 goroutine:
go b.s()
这是从 b.c
收到的,也是从 b.a.c
收到的:
func (b *b) s() {
for {
select {
case <-b.c:
fmt.Println("b c")
b.a.do()
case <-b.a.c:
fmt.Println("b a c")
}
}
}
如果从 b.c
收到一个值,这个 goroutine 会尝试在 b.a.c
上发送(在 a.do()
方法中),而你期望这个 same goroutine 从 b.a.c
接收。但是由于 b.a.c
是无缓冲的,发送将阻塞,因此它永远不会到达 b.s()
中的下一次迭代,它可以/将从 b.a.c
.
如果一个通道没有缓冲,只有当有另一个 goroutine 准备好从它接收时,它的发送才能继续。
如果您使 b.a.c
通道缓冲,发送可以在不阻塞的情况下继续进行,因此在下一次迭代中可以接收它:
a: a{c: make(chan bool, 1)}
通过此更改,您将获得预期的输出。在 Go Playground.
上试试