问题
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:
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 "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")
}
回答2:
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 = <-
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:
See the relevant section in the Go language spec: http://golang.org/ref/spec#Receive_operator
回答4:
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.
来源:https://stackoverflow.com/questions/10437015/does-a-channel-return-two-values