一个通道是否返回两个值?

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

Does a channel return two values?

问题

第二个值(ok)表示通道是否成功接收到数据。如果ok为true,则表示通道成功接收到数据,并且可以使用接收到的数据。如果ok为false,则表示通道已关闭或者没有数据可接收。在代码中,如果ok为true,则调用self.onServer(serverData)或self.onUser(userInput)来处理接收到的数据。如果ok为false,则将self.isRunning设置为false,停止循环。

英文:

I saw some code in this link, and got confused:http://www.darkcoding.net/software/go-lang-after-four-months/

What's the meaning of the second value(ok)?

for self.isRunning {

    select {
    case serverData, ok = <-fromServer:   // What's the meaning of the second value(ok)?
        if ok {
            self.onServer(serverData)
        } else {
            self.isRunning = false
        }

    case userInput, ok = <-fromUser:
        if ok {
            self.onUser(userInput)
        } else {
            self.isRunning = false
        }
    }

}

答案1

得分: 42

布尔变量ok接收操作符返回,指示接收到的值是通过通道发送的(true),还是因为通道关闭且为空而返回的零值(false)。

当Go程序的其他部分关闭fromServerfromUser通道时,for循环终止。在这种情况下,其中一个case语句将把ok设置为true。因此,如果用户关闭连接或远程服务器关闭连接,程序将终止。

http://play.golang.org/p/4fJDkgaa9O:

package main

import "runtime"

func onServer(i int) { println("S:", i) }
func onUser(i int)   { println("U:", i) }

func main() {
    fromServer, fromUser := make(chan int),make(chan int)
    var serverData, userInput int
    var ok bool

    go func() {
        fromServer <- 1
        fromUser <- 1
        close(fromServer)
        runtime.Gosched()
        fromUser <- 2
        close(fromUser)
    }()

    isRunning := true
    for isRunning {
        select {
            case serverData, ok = <-fromServer:
                if ok {
                    onServer(serverData)
                } else {
                    isRunning = false
                }

            case userInput, ok = <-fromUser:
                if ok {
                    onUser(userInput)
                } else {
                    isRunning = false
                }
            }
        }
        println("end")
}
英文:

The boolean variable ok returned by a receive operator indicates whether the received value was sent on the channel (true) or is a zero value returned because the channel is closed and empty (false).

The for loop terminates when some other part of the Go program closes the fromServer or the fromUser channel. In that case one of the case statements will set ok to true. So if the user closes the connection or the remote server closes the connection, the program will terminate.

http://play.golang.org/p/4fJDkgaa9O:

package main

import &quot;runtime&quot;

func onServer(i int) { println(&quot;S:&quot;, i) }
func onUser(i int)   { println(&quot;U:&quot;, i) }

func main() {
    fromServer, fromUser := make(chan int),make(chan int)
    var serverData, userInput int
    var ok bool

    go func() {
        fromServer &lt;- 1
        fromUser &lt;- 1
        close(fromServer)
        runtime.Gosched()
        fromUser &lt;- 2
        close(fromUser)
    }()

    isRunning := true
    for isRunning {
        select {
            case serverData, ok = &lt;-fromServer:
                if ok {
                    onServer(serverData)
                } else {
                    isRunning = false
                }

            case userInput, ok = &lt;-fromUser:
                if ok {
                    onUser(userInput)
                } else {
                    isRunning = false
                }
            }
        }
        println(&quot;end&quot;)
}

答案2

得分: 13

有几个答案引用了接收操作符的规范,但是要理解的话,你可能还需要阅读一下关闭函数的规范。然后,由于你会想知道为什么这些特性是这样的,可以阅读一下for语句如何遍历通道。for语句需要一个信号来停止迭代,而close就是发送者表示“没有更多数据”的方式。

通过将close, ok = <-作为语言的一部分公开,你可以在其他情况下使用它们,当你希望发送的goroutine发出“没有更多数据”的信号时。问题中的示例代码是对这些特性的有趣应用。它同时处理了“服务器”通道和“用户”通道,如果从任何一个通道接收到“没有更多数据”的信号,它就会跳出循环。

英文:

A couple of answers have cited the spec on the receive operator, but to understand you probably need to read the spec on the close function as well. Then since you'll be wondering why these features are the way they are, read how the for statement ranges over a channel. The for statement needs a signal to stop iteration and close is the way a sender can say "no more data".

With close and , ok = &lt;- exposed as part of the language, you can use them in other cases when you wish a sending goroutine to signal "no more data". The example code in the question is an interesting use of these features. It is handling both a "server" channel and a "user" channel, and if a "no more data" signal arrives from either of them, it breaks out of the loop.

答案3

得分: 2

请参阅Go语言规范中的相关部分:
http://golang.org/ref/spec#Receive_operator

英文:

See the relevant section in the Go language spec:
http://golang.org/ref/spec#Receive_operator

答案4

得分: 0

在Go语言中,函数和通道可以返回多个值。其中,ok必须是一个布尔变量,值为true(成功)或false(失败),而serverData则是从通道接收到的实际数据。

英文:

In Go, functions & channels can return more than 1 value. Here ok must be a boolean variable with true (successful) and false (unsuccessful) and serverData is the actual data received from the channel.

huangapple
  • 本文由 发表于 2012年5月4日 02:09:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/10437015.html
匿名

发表评论

匿名网友

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

确定