29

我在这个链接中看到了一些代码,很困惑:http ://www.darkcoding.net/software/go-lang-after-four-months/

第二个值(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
        }
    }

}
4

4 回答 4

33

接收运算符ok返回的布尔变量指示接收到的值是在通道上发送的 (true) 还是由于通道关闭且为空 (false) 而返回的零值。

forGo 程序的其他部分关闭fromServerfromUser通道时,循环终止。在这种情况下,其中一个 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")
}
于 2012-05-03T19:41:28.790 回答
11

有几个答案引用了接收运算符的规范,但要了解您可能还需要阅读close 函数的规范。然后,既然您会想知道为什么这些功能是这样的,请阅读for 语句在通道上的范围。for 语句需要一个信号来停止迭代,并且close是发送者可以说“没有更多数据”的方式。

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

于 2012-05-03T20:37:44.143 回答
2

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

于 2012-05-03T19:37:41.807 回答
-1

在 Go 中,函数和通道可以返回超过 1 个值。这里 ok 必须是一个布尔变量,具有 true(成功)和 false(不成功),serverData 是从通道接收到的实际数据。

于 2012-05-03T18:13:20.713 回答