首页 > 解决方案 > 是否可以在 Golang 中使用“选择”访问通道 ch1、ch2?

问题描述

我试图调试这段代码,但被困在这里。我想访问 ch1, ch2 但发现什么也没打印。

package main

import (
    "fmt"
)

type degen struct {
    i, j string
}

func (x degen) CVIO(ch1, ch2 chan string, quit chan int, m, n string) {
    for {
        select {
        case ch1 <- m:
            fmt.Println(x.i)
        case ch2 <- n:
            fmt.Println("ok")
        case <-quit:
            fmt.Println("quit")
            return
        }
    }

}

func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)
    quit := make(chan int)
    x := degen{"goosebump", "ok"}
    go x.CVIO(ch1, ch2, quit, "goosebump", "ok")
}

期望:它应该打印要生成的通道数据。

标签: gomethodsstruct

解决方案


它不是很清楚你期望你的代码做什么:

  • main()无需等待 go 例程退出就结束(很可能循环根本不会运行)。
  • select由于没有接收者,发送将不会继续(规范- “如果容量为零或不存在,则通道是无缓冲的,并且只有在发送者和接收者都准备好时通信才会成功。”)。
  • 没有任何东西发送到quit通道。

我怀疑以下(游乐场)可能会满足您的期望。

package main

import (
    "fmt"
    "sync"
)

type degen struct {
    i, j string
}

func (x degen) CVIO(ch1, ch2 chan string, quit chan int, m, n string) {
    for {
        select {
        case ch1 <- m:
            fmt.Println(x.i)
        case ch2 <- n:
            fmt.Println("ok")
        case <-quit:
            fmt.Println("quit")
            return
        }
    }

}

func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)
    quit := make(chan int)
    x := degen{"goosebump", "ok"}
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        x.CVIO(ch1, ch2, quit, "goosebump", "ok")
        wg.Done()
    }()

    <-ch1 // Receive from CH1 (allowing "ch1 <- m" in go routine to proceed)
    <-ch2 // Receive from CH2 (allowing "ch2 <- n" in go routine to proceed)

    quit <- 1
    wg.Wait() // Wait for CVIO to end (which it should do due to above send)
}

推荐阅读