Go 选择仅从一个通道打印输出

Go 选择仅从一个通道打印输出,go,goroutine,Go,Goroutine,我正在学习围棋,我现在在频道上。我用通道写了一个简单的程序。我已经创建了两个通道,这些通道被传递给一个并发调用的函数 我的期望是从两个通道打印输出,但实际上只有一个通道输出被打印: package main import "fmt" func square(dat int, ch chan<- int) { ch <- dat * dat } func main() { resp1 := make(chan int) resp2 := make(c

我正在学习围棋,我现在在频道上。我用通道写了一个简单的程序。我已经创建了两个通道,这些通道被传递给一个并发调用的函数

我的期望是从两个通道打印输出,但实际上只有一个通道输出被打印:

package main

import "fmt"

func square(dat int, ch chan<- int) {

    ch <- dat * dat

}

func main() {

    resp1 := make(chan int)
    resp2 := make(chan int)

    go square(20, resp1)
    go square(10, resp2)

    select {
    case msg1 := <-resp1:
        fmt.Println(msg1)
    case msg2 := <-resp2:
        fmt.Println(msg2)
    }
}
主程序包
输入“fmt”
func square(国际数据中心,陈氏)

“select”语句选择一组可能的发送或发送选项中的哪一个 接收操作将继续

选择选择集合中的一个。例如

package main

import "fmt"

func square(dat int, ch chan<- int) {

    ch <- dat * dat

}

func main() {

    resp1 := make(chan int)
    resp2 := make(chan int)

    go square(20, resp1)
    go square(10, resp2)

    // Choose one
    select {
    case msg1 := <-resp1:
        fmt.Println(msg1)
    case msg2 := <-resp2:
        fmt.Println(msg2)
    }
    // Choose the other
    select {
    case msg1 := <-resp1:
        fmt.Println(msg1)
    case msg2 := <-resp2:
        fmt.Println(msg2)
    }
}

您希望
select
同时选择两者吗?这与它的用途正好相反。从:

“select”语句选择一组可能的发送或接收操作中的哪一个将继续

如果一个或多个通信可以进行,则通过均匀伪随机选择选择可以进行的单个通信

如果您想从两个通道读取数据,而不是让
选择
找出哪个通道可以读取(或者如果两个通道都可以读取,则伪随机选择一个),不要使用
选择
。只需从两个通道读取:

msg1 := <-resp1:
fmt.Println(msg1)
msg2 := <-resp2:
fmt.Println(msg2)

msg1:=根据您在“选择”中的代码,无论何时,只要有任何大小写匹配就会执行,主功能就会终止。这就是为什么它只打印单通道值的原因。
您可以通过执行以下操作来解决此问题:

package main

import (
    "fmt"
    "os"
    "time"
)

func square(dat int, ch chan<- int) {
    ch <- dat * dat
}

func main() {
    resp1 := make(chan int)
    resp2 := make(chan int)

    go square(20, resp1)
    go square(10, resp2)
    time.Sleep(1 * time.Second)
    for {
        select {
        case msg1 := <-resp1:
            fmt.Println(msg1)
        case msg2 := <-resp2:
            fmt.Println(msg2)
        default:
            close(resp1)
            close(resp2)
            fmt.Println("no value recieved")
            os.Exit(0)
        }
    }
}

在操场上看:

选择在另一种语言(例如Java)中更像是一个开关,你需要根据需要执行该部分N次。

@peterSO也许吧?很可能你正确地猜测了询问者的意图。然而,这个问题肯定没有提到任何相关内容。提出的问题似乎是“为什么
select
只选择一个案例?”答案是“这就是
select
的目的。”
func main() {
    resp1 := make(chan int)
    resp2 := make(chan int)

    readsWanted := 0

    readsWanted += 1
    go square(20, resp1)
    readsWanted += 1
    go square(10, resp2)

    for i := 0; i < readsWanted; i++ {
        select {
        case msg1 := <-resp1:
            fmt.Println(msg1)
        case msg2 := <-resp2:
            fmt.Println(msg2)
        }
    }
}
package main

import (
    "fmt"
    "os"
    "time"
)

func square(dat int, ch chan<- int) {
    ch <- dat * dat
}

func main() {
    resp1 := make(chan int)
    resp2 := make(chan int)

    go square(20, resp1)
    go square(10, resp2)
    time.Sleep(1 * time.Second)
    for {
        select {
        case msg1 := <-resp1:
            fmt.Println(msg1)
        case msg2 := <-resp2:
            fmt.Println(msg2)
        default:
            close(resp1)
            close(resp2)
            fmt.Println("no value recieved")
            os.Exit(0)
        }
    }
}
100
400
no value recieved