goroutine通道 – 发送语句的值

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

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 &lt;- x:
                x, y = y, x + y
            case &lt;-quit:
                fmt.Println(&quot;quit&quot;)
                return
            }
        }
    }

Thank you

答案1

得分: 8

这是真的,c <- x 是一个语句,没有返回值。

你可能把 selectswitch 搞混了。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 &lt;- 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 &lt;- 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.

huangapple
  • 本文由 发表于 2012年4月14日 08:57:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/10150116.html
匿名

发表评论

匿名网友

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

确定