在Golang中,可以使用`select`关键字来访问通道ch1和ch2吗?

huangapple go评论112阅读模式
英文:

Is it possible to access channels ch1, ch2 using `select` in Golang?

问题

我正在尝试调试这段代码,但卡在这里。我想要访问ch1和ch2,但发现没有打印任何内容。

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type degen struct {
  6. i, j string
  7. }
  8. func (x degen) CVIO(ch1, ch2 chan string, quit chan int, m, n string) {
  9. for {
  10. select {
  11. case ch1 <- m:
  12. fmt.Println(x.i)
  13. case ch2 <- n:
  14. fmt.Println("ok")
  15. case <-quit:
  16. fmt.Println("quit")
  17. return
  18. }
  19. }
  20. }
  21. func main() {
  22. ch1 := make(chan string)
  23. ch2 := make(chan string)
  24. quit := make(chan int)
  25. x := degen{"goosebump", "ok"}
  26. go x.CVIO(ch1, ch2, quit, "goosebump", "ok")
  27. }

期望的结果:
它应该打印即将产生的通道数据。

英文:

I was trying to debug this code but am stuck here. I wanted to access ch1, ch2 but found printed nothing.

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. )
  5. type degen struct {
  6. i, j string
  7. }
  8. func (x degen) CVIO(ch1, ch2 chan string, quit chan int, m, n string) {
  9. for {
  10. select {
  11. case ch1 &lt;- m:
  12. fmt.Println(x.i)
  13. case ch2 &lt;- n:
  14. fmt.Println(&quot;ok&quot;)
  15. case &lt;-quit:
  16. fmt.Println(&quot;quit&quot;)
  17. return
  18. }
  19. }
  20. }
  21. func main() {
  22. ch1 := make(chan string)
  23. ch2 := make(chan string)
  24. quit := make(chan int)
  25. x := degen{&quot;goosebump&quot;, &quot;ok&quot;}
  26. go x.CVIO(ch1, ch2, quit, &quot;goosebump&quot;, &quot;ok&quot;)
  27. }

Desired:
It should print the channel data as to be produced.

答案1

得分: 3

你的代码的预期功能并不是很清楚:

  • main() 函数在结束时没有等待 go 协程退出(循环可能根本不会运行)。
  • select 语句中,发送操作无法进行,因为没有接收者(参考 规范 - "如果容量为零或不存在,则通道是无缓冲的,只有在发送方和接收方都准备好时通信才会成功。")。
  • 没有向 quit 通道发送任何内容。

我怀疑以下代码(playground)可能会实现你的预期功能。

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. type degen struct {
  7. i, j string
  8. }
  9. func (x degen) CVIO(ch1, ch2 chan string, quit chan int, m, n string) {
  10. for {
  11. select {
  12. case ch1 <- m:
  13. fmt.Println(x.i)
  14. case ch2 <- n:
  15. fmt.Println("ok")
  16. case <-quit:
  17. fmt.Println("quit")
  18. return
  19. }
  20. }
  21. }
  22. func main() {
  23. ch1 := make(chan string)
  24. ch2 := make(chan string)
  25. quit := make(chan int)
  26. x := degen{"goosebump", "ok"}
  27. var wg sync.WaitGroup
  28. wg.Add(1)
  29. go func() {
  30. x.CVIO(ch1, ch2, quit, "goosebump", "ok")
  31. wg.Done()
  32. }()
  33. <-ch1 // 从 CH1 接收(允许 go 协程中的 "ch1 <- m" 继续执行)
  34. <-ch2 // 从 CH2 接收(允许 go 协程中的 "ch2 <- n" 继续执行)
  35. quit <- 1
  36. wg.Wait() // 等待 CVIO 结束(由于上述发送操作,它应该会结束)
  37. }

希望对你有帮助!

英文:

Its not really clear what you expect your code to do:

  • main() ends without waiting for the go routine to exit (its quite possible it the loop will not run at all).
  • in the select the sends will not proceed because there is no receiver (spec - "if the capacity is zero or absent, the channel is unbuffered and communication succeeds only when both a sender and receiver are ready.").
  • Nothing is sent to the quit channel.

I suspect that the following (playground) might do what you were expecting.

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;sync&quot;
  5. )
  6. type degen struct {
  7. i, j string
  8. }
  9. func (x degen) CVIO(ch1, ch2 chan string, quit chan int, m, n string) {
  10. for {
  11. select {
  12. case ch1 &lt;- m:
  13. fmt.Println(x.i)
  14. case ch2 &lt;- n:
  15. fmt.Println(&quot;ok&quot;)
  16. case &lt;-quit:
  17. fmt.Println(&quot;quit&quot;)
  18. return
  19. }
  20. }
  21. }
  22. func main() {
  23. ch1 := make(chan string)
  24. ch2 := make(chan string)
  25. quit := make(chan int)
  26. x := degen{&quot;goosebump&quot;, &quot;ok&quot;}
  27. var wg sync.WaitGroup
  28. wg.Add(1)
  29. go func() {
  30. x.CVIO(ch1, ch2, quit, &quot;goosebump&quot;, &quot;ok&quot;)
  31. wg.Done()
  32. }()
  33. &lt;-ch1 // Receive from CH1 (allowing &quot;ch1 &lt;- m&quot; in go routine to proceed)
  34. &lt;-ch2 // Receive from CH2 (allowing &quot;ch2 &lt;- n&quot; in go routine to proceed)
  35. quit &lt;- 1
  36. wg.Wait() // Wait for CVIO to end (which it should do due to above send)
  37. }

huangapple
  • 本文由 发表于 2021年9月13日 17:02:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/69159990.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定