为什么通道没有接收到成为结构体的成员

代码: 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?


代码是不言自明的,如果还需要更多详细信息,请询问


ibeautiful
浏览 103回答 1
1回答

杨魅力

你的maingoroutine 在 上发送一个值b.c,然后等待:b.c <- true从 main 启动的 goroutine:go b.s()这是从 接收的b.c,也是从 接收的b.a.c:func (b *b) s() {&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-b.c:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("b c")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b.a.do()&nbsp; &nbsp; &nbsp; &nbsp; case <-b.a.c:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("b a c")&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}如果从 接收到一个值b.c,则该 goroutine 会尝试发送b.a.c(在a.do()方法中),并且您希望同一个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上尝试一下。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go