Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a channel that receive multiple return values from a goroutine

Tags:

go

I have a function in Go that returns two values. I want to run this as a goroutine, but I can't figure out the syntax for creating a channel that receives two values. Could someone point me in the right direction?

like image 775
Sam Lee Avatar asked Jul 24 '13 05:07

Sam Lee


People also ask

Can you return from a Goroutine?

Channels can be used to fetch return value from a goroutine. Channels provide synchronization and communication between goroutines. You can send the return value in a channel in the goroutine and then collect that value in the main function. This line will wait until a value is pushed to the result channel.

How do you find the return value of a Goroutine?

The most natural way to fetch a value from a goroutine is channels. Channels are the pipes that connect concurrent goroutines. You can send values into channels from one goroutine and receive those values into another goroutine or in a synchronous function.

Is Goroutine a concurrency?

Goroutines are functions or methods that run concurrently with other functions or methods. Goroutines can be thought of as lightweight threads. The cost of creating a Goroutine is tiny when compared to a thread. Hence it's common for Go applications to have thousands of Goroutines running concurrently.

How do I use Goroutine channel?

If goroutines are the activities of a concurrent Go program, channels are the connections between them. A channel is a communication mechanism that enables one goroutine to send values to another goroutine. Each channel is a conduit for values of a particular type, called the channel's element type.


1 Answers

Define a custom type with fields for both values, then create a chan of that type.

EDIT: I've also added an example (right at the bottom) that uses multiple channels rather than a custom type. I'm not sure which is more idiomatic.

For example:

type Result struct {     Field1 string     Field2 int } 

then

ch := make(chan Result) 

Example of using a channel of a custom type (Playground):

package main  import (     "fmt"     "strings" )  type Result struct {     allCaps string     length  int }  func capsAndLen(words []string, c chan Result) {     defer close(c)     for _, word := range words {         res := new(Result)         res.allCaps = strings.ToUpper(word)         res.length = len(word)         c <- *res            } }  func main() {     words := []string{"lorem", "ipsum", "dolor", "sit", "amet"}     c := make(chan Result)     go capsAndLen(words, c)     for res := range c {         fmt.Println(res.allCaps, ",", res.length)     } } 

Produces:

LOREM , 5
IPSUM , 5
DOLOR , 5
SIT , 3
AMET , 4

EDIT: Example using multiple channels instead of a custom type to produce the same output (Playground):

package main  import (     "fmt"     "strings" )  func capsAndLen(words []string, cs chan string, ci chan int) {     defer close(cs)     defer close(ci)     for _, word := range words {         cs <- strings.ToUpper(word)         ci <- len(word)     } }  func main() {     words := []string{"lorem", "ipsum", "dolor", "sit", "amet"}     cs := make(chan string)     ci := make(chan int)     go capsAndLen(words, cs, ci)     for allCaps := range cs {         length := <-ci         fmt.Println(allCaps, ",", length)     } } 
like image 54
Intermernet Avatar answered Sep 27 '22 23:09

Intermernet