29

このリンクでいくつかのコードを見て、混乱しました: http://www.darkcoding.net/software/go-lang-after-four-months/

2 番目の値 (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

receive オペレーターokによって返されるboolean 変数は、受信した値がチャネルで送信されたか (true)、またはチャネルが閉じられていて空であるために返されたゼロ値であるか (false) を示します。

Go プログラムのfor他の部分がfromServerまたはfromUserチャネルを閉じると、ループは終了します。その場合、case ステートメントの 1 つがoktrue に設定されます。そのため、ユーザーが接続を閉じるか、リモート サーバーが接続を閉じると、プログラムは終了します。

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

いくつかの回答で receive 演算子の仕様が引用されていますが、理解するには、おそらくclose 関数の仕様も読む必要があります。次に、なぜこれらの機能がこのようになっているのか不思議に思うので、for ステートメントがチャネルにどのように影響するかを読んでください。for ステートメントは反復を停止するシグナルを必要としclose、送信者が「これ以上データがありません」と言うことができる方法です。

closeを使用, ok = <-して、言語の一部として公開することで、送信ゴルーチンで「これ以上データがありません」というシグナルを送信したい場合に、これらを使用できます。問題のコード例は、これらの機能の興味深い使い方です。「サーバー」チャネルと「ユーザー」チャネルの両方を処理しており、いずれかから「データがなくなった」という信号が到着すると、ループから抜け出します。

于 2012-05-03T20:37:44.143 に答える
2

Go 言語仕様の関連セクションを参照してください: http://golang.org/ref/spec#Receive_operator

于 2012-05-03T19:37:41.807 に答える
-1

Go では、関数とチャネルは複数の値を返すことができます。ここで、ok は true (成功) と false (失敗) のブール変数である必要があり、serverData はチャネルから受信した実際のデータです。

于 2012-05-03T18:13:20.713 に答える