How to use goroutine return value? [SOLVED]


GO, GOLANG Solutions

Author: Tuan Nguyen
Reviewer: Deepak Prasad

In this tutorial, we will try to catch return values from goroutines. Fetching the return value from a function and running a goroutine (asynchronously) are essentially incompatible activities. We use the goroutines when we want to run them separately from the main goroutine. But when you assign the return value from a function to a variable you are expecting to have this value within the variable. It means you have to wait for the function to return the value and then continue the next steps in the main function.

Channels are the most intuitive way to retrieve a value from a goroutine. Channels are the pipes that link running goroutines. One goroutine can transmit values through channels, while another goroutine or synchronous function can receive those values.

 

Example 1: Using channel to fetch return value from goroutines

Fetch single value from goroutine

In this example we will use golang channel to fetch the goroutine return value:

package main

import "fmt"

func main() {
	result := make(chan int, 1)
	go multiply(8, 9, result)

	// catching return
	value := <-result
	fmt.Printf("Returned Value from goroutine: %d\n", value)
	close(result)

}

func multiply(a, b int, result chan int) {
	mul := a * b
	// send the result to channel
	result <- mul
}

Output:

Returned Value from goroutine: 72

In the main function we will wait for the channel to receive the return value from the goroutine:

value := <-result

This line will wait until a value is added to the channel. So even if we add a time.Sleep to the goroutine, our main goroutine still hangs until the channel receives the returned value from goroutine and the output will be the same as the below example:

How to use goroutine return value? [SOLVED]

 

Fetch multiple return values from goroutines

You can retrieve a goroutine's return value using channels. Goroutine synchronization and communication are provided by channels. To receive multiple return values from a goroutine, we can create a struct whose fields are the returned value, then create a channel of that type. Let’s see an example of fetching multiple return values from a goroutine using a channel:

package main

import (
	"fmt"
	"time"
)

type Result struct {
	Sum      int
	Multiply int
	Subtract int
}

func main() {
	result := make(chan Result, 1)
	go operation(8, 9, result)

	// catching return struct from channel
	value := <-result
	fmt.Printf("Retured struct: %+v\n", value)
	close(result)

}

func operation(a, b int, result chan Result) {
	mul := a * b
	sum := a + b
	sub := a - b

	returnValues := Result{Sum: sum, Multiply: mul, Subtract: sub}
	// set time.Sleep for goroutine
	time.Sleep(time.Second * 3)
	// return a struct
	result <- returnValues
}

Output:

Retured struct: {Sum:17 Multiply:72 Subtract:-1}

 

Example 2: Directly assign return value from goroutine to a variable

The example below shows how we can directly assign the return value from a goroutine to a variable:

package main

import (
	"fmt"
	"time"
)

func main() {
	var mul int

	go func() {
		mul = 8 * 9
	}()

        // sleep a little bit for goroutine to update the variable 
	time.Sleep(time.Second * 3)
	fmt.Println("Returned value from goroutine:", mul)
}

Output:

Returned value from goroutine: 72

We can see that we can update the variable inside the goroutine. But we have to do a trick: time.Sleep() to wait for the goroutine to change the variable. So the problem with this method is how are you going to use the variable from the original goroutine? We have to make sure the goroutine has already updated the value before using it. We can use a WaitGroup to ensure the goroutine has done its job but it does not make sense. We better use a channel to get the return value from a goroutine.

 

Summary

After trying some examples of how to catch the return values from goroutines, we can see that using the channel is the best practice way. We also can directly update the variable inside the goroutine but it is very hard to keep track of when the variable is updated.

 

References

https://go.dev/tour/concurrency/1
https://pkg.go.dev/sync
Catching return values from goroutines - Stack Overflow

 

Tuan Nguyen

Tuan Nguyen

He is proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise spanning these technologies, he develops robust solutions and implements efficient data processing and management strategies across various projects and platforms. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment