英文:
goroutine channels - the value of send statement
问题
当我尝试在下面的代码块中的for循环之前打印出<pre>fmt.Println(c <- x)</pre>来查看"c <- x"的评估结果时,出现了错误信息:
./select.go:7: send statement c <- x used as value; use select for non-blocking send
如果发送操作成功,"c <- x"是否被评估为true?为什么Go只允许在select语句的case语句内部使用发送语句的值(即"c <- x"的值)?
谢谢
英文:
When I tried to print out: <pre>fmt.Println(c <- x)</pre> right before the for loop in the code block below to see what "c <- x" would evaluate to, it got the error message:
./select.go:7: send statement c <- x used as value; use select for non-blocking send
Is "c <- x" evaluated to true if the sending operation was successful? And why does Go only let you use the value of the send statement (aka value of "c <- x") inside case statements inside a select statement?
func fibonacci(c, quit chan int) {
x, y := 1, 1
for {
select {
case c <- x:
x, y = y, x + y
case <-quit:
fmt.Println("quit")
return
}
}
}
Thank you
答案1
得分: 8
这是真的,c <- x
是一个语句,没有返回值。
你可能把 select
和 switch
搞混了。Switch 通过匹配或评估为 true 的 case 表达式来工作。而 select 则是寻找非阻塞的 case,选择其中一个让其继续执行,然后运行 case 块中的语句。
所以,当发送操作成功时,c <- x
并不会被评估为 true。相反,case 块中的语句 x, y = y, x + y
会被执行。没有发送的结果,也没有 true 值被存储在任何地方。
你可能读到过,在 接收 操作中,使用短声明赋值的变量只在 case 块的作用域内。这是正确的(尽管上面的 select 语句的 case 中没有短声明)。如果你想在 case 块结束后使用接收到的值,你可以使用简单的赋值而不是短声明。
参考:select 语句的语言规范。它真的非常易读。
英文:
It's true, c <- x
is a statement and has no value.
You may be confusing select
with switch
. Switch works by seeing which case expression matches or evaluates to true. Select, on the other hand, looks for cases which are not blocking, picks one of them to allow to proceed, and then runs the statements in the case block.
So no, c <- x
is not evaluated to true wen the sending operation is successful. Instead, the statement of the case block, x, y = y, x + y
is simply executed. There is no result of a send, no true value, stored anywhere.
You may have read that for a receive operation, a variable assigned with a short declarion is only in the scope of the case block. This is true (although there are no short declarations in the cases of the select statement above.) If you had a case where you wanted a received value after the case block ends, you would use a simple assignment and not a short declaration.
Oblig: the language spec on the select statement. It's really very readable.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论