猿问

在同一选定案例中接收和发送

我需要将一个通道的结果转发到另一个通道。我用了这样的东西:


for {

        select {

        ...

        case ch2 <- (<-ch1):

        ...

        }

}

这似乎很完美,但这里到底发生了什么?select 语句是在接收操作和/或发送操作上选择的?


我知道选择语句可以单独选择:


select {

    case ch <- v:

}

select {                                                                         

    case v = <- ch:

}


BIG阳
浏览 102回答 2
2回答

侃侃无极

从文档中:对于语句中的所有情况,在输入 “select” 语句时,接收操作的通道操作数以及 send 语句的通道和右侧表达式将按源顺序计算一次。结果是一组要从中接收或发送到的通道,以及要发送的相应值。无论选择哪个(如果有)通信操作继续进行,都将发生该评估中的任何副作用。尚未计算 RecvStmt 左侧具有短变量声明或赋值的表达式。这意味着:case&nbsp;ch2&nbsp;<-&nbsp;(<-ch1):将立即阻止从 接收,然后将控制是否发生发送或不同。ch1selectch2case迪斯科的赞美诗说得很好;将其视为 ,其中在输入 时进行评估。selectch2 <- <something><something>select它还具有消耗和丢弃值的副作用,如果该值最终不是所选的值。ch1case

函数式编程

正如阿德里安所回答的那样,这绝对是错误的方法。如果您想在某个退出频道说退出之前接收和转发数据,则需要以下或类似内容:func copyInputUntil(output, input chan T, quit chan struct{}) {&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; var v T&nbsp; &nbsp; &nbsp; &nbsp; // wait for input value, or quit&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-quit: return // maybe: close(output), too (via earlier defer)&nbsp; &nbsp; &nbsp; &nbsp; case v = <-input:&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // wait to send it&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-quit: return&nbsp; &nbsp; &nbsp; &nbsp; case output <- v:&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}这可以作为自己的goroutine剥离出来。这不太现实,当然这是低效的:你最好只是让发送者直接发送到正确的渠道,而不是让这个愚蠢的goroutine介于两者之间。尽管如此,我还是把这一切都变成了围棋操场上一个完整的例子。
随时随地看视频慕课网APP

相关分类

Go
我要回答