如何从goroutine中返回多个值?

huangapple go评论72阅读模式
英文:

How to return multiple values from goroutine?

问题

我找到了一个关于“从 Goroutines 中捕获值”的示例,链接

示例中展示了如何获取值,但如果我想从多个 Goroutines 中返回值,它将无法工作。所以,有人知道如何做吗?

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"sync"
)

// WaitGroup 用于等待程序完成 Goroutines。
var wg sync.WaitGroup

func responseSize(url string, nums chan int) {
	// 调用 WaitGroup 的 Done 方法告诉 Goroutine 已完成。
	defer wg.Done()

	response, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}
	defer response.Body.Close()
	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Fatal(err)
	}
	// 将值发送到无缓冲通道
	nums <- len(body)
}

func main() {
	nums := make(chan int) // 声明一个无缓冲通道
	wg.Add(1)
	go responseSize("https://www.golangprograms.com", nums)
	go responseSize("https://gobyexample.com/worker-pools", nums)
	go responseSize("https://stackoverflow.com/questions/ask", nums)
	fmt.Println(<-nums) // 从无缓冲通道中读取值
	wg.Wait()
	close(nums) // 关闭通道
	// >> 永远加载中
}

另外,这个例子是关于worker pools的。

fmt.Println(<-results) 这行代码中获取值是不可能的,会导致错误。

英文:

I found some example with "Catch values from Goroutines"-> link

There is show how to fetch value but if I want to return value from several goroutines, it wont work.So, does anybody know, how to do it?

 package main

import (
	&quot;fmt&quot;
	&quot;io/ioutil&quot;
	&quot;log&quot;
	&quot;net/http&quot;
	&quot;sync&quot;
)

// WaitGroup is used to wait for the program to finish goroutines.
var wg sync.WaitGroup

func responseSize(url string, nums chan int) {
	// Schedule the call to WaitGroup&#39;s Done to tell goroutine is completed.
	defer wg.Done()

	response, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}
	defer response.Body.Close()
	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Fatal(err)
	}
	// Send value to the unbuffered channel
	nums &lt;- len(body)
}

func main() {
	nums := make(chan int) // Declare a unbuffered channel
	wg.Add(1)
	go responseSize(&quot;https://www.golangprograms.com&quot;, nums)
    go responseSize(&quot;https://gobyexample.com/worker-pools&quot;, nums)
    go responseSize(&quot;https://stackoverflow.com/questions/ask&quot;, nums)
	fmt.Println(&lt;-nums) // Read the value from unbuffered channel
	wg.Wait()
	close(nums) // Closes the channel
    // &gt;&gt; loading forever

Also, this example, worker pools

Is it possible to get value from result: fmt.Println(&lt;-results) <- will be error.

答案1

得分: 3

是的,只需多次从通道中读取即可:

answerOne := <-nums
answerTwo := <-nums
answerThree := <-nums

通道的功能类似于线程安全的队列,允许您将值排队并逐个读取出来。

附注:您应该将等待组增加3次,或者根本不使用等待组。<-nums 将会阻塞,直到 nums 上有一个可用的值,因此不需要等待组。

英文:

Yes, just read from the channel multiple times:

answerOne := &lt;-nums
answerTwo := &lt;-nums
answerThree := &lt;-nums

Channels function like thread-safe queues, allowing you to queue up values and read them out one by one

P.S. You should either add 3 to the wait group or not have one at all. The <-nums will block until a value is available on nums so it is not necessary

huangapple
  • 本文由 发表于 2022年9月3日 06:32:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/73588427.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定