In Go language, you are allowed to return multiple values from a function, using the return statement. Or in other words, in function, a single return statement can return multiple values. The type of the return values is similar to the type of the parameter defined in the parameter list.
Functions in Golang can return multiple values, which is a helpful feature in many practical scenarios. This example declares a function with two return values and calls it from a main function.
Go channels are used for communicating between concurrently running functions by sending and receiving a specific element type's data. When we have numerous Goroutines running at the same time, channels are the most convenient way for them to communicate with one another.
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")
}
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.
See the relevant section in the Go language spec: http://golang.org/ref/spec#Receive_operator
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With