Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a channel return two values?

Tags:

go

channel

People also ask

Can go return multiple values?

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.

How many values a Go function can return?

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.

What are channels used for in go?

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