如何创建一个通道来接收goroutine返回的多个值

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

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

问题

我在Go中有一个返回两个值的函数。我想将其作为goroutine运行,但是我无法弄清楚创建一个接收两个值的通道的语法。有人可以指点我正确的方向吗?

英文:

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?

答案1

得分: 67

定义一个具有两个值字段的自定义类型,然后创建一个该类型的chan

例如:

type Result struct {
    Field1 string
    Field2 int
}

然后

ch := make(chan Result)

使用自定义类型的通道的示例(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)
    }
}

输出:

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

使用多个通道而不是自定义类型来产生相同输出的示例(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)
    }
}
英文:

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 (
	&quot;fmt&quot;
	&quot;strings&quot;
)

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 &lt;- *res		
	}
}

func main() {
	words := []string{&quot;lorem&quot;, &quot;ipsum&quot;, &quot;dolor&quot;, &quot;sit&quot;, &quot;amet&quot;}
	c := make(chan Result)
	go capsAndLen(words, c)
	for res := range c {
		fmt.Println(res.allCaps, &quot;,&quot;, 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 (
	&quot;fmt&quot;
	&quot;strings&quot;
)

func capsAndLen(words []string, cs chan string, ci chan int) {
	defer close(cs)
	defer close(ci)
	for _, word := range words {
		cs &lt;- strings.ToUpper(word)
		ci &lt;- len(word)
	}
}

func main() {
	words := []string{&quot;lorem&quot;, &quot;ipsum&quot;, &quot;dolor&quot;, &quot;sit&quot;, &quot;amet&quot;}
	cs := make(chan string)
	ci := make(chan int)
	go capsAndLen(words, cs, ci)
	for allCaps := range cs {
		length := &lt;-ci
		fmt.Println(allCaps, &quot;,&quot;, length)
	}
}

答案2

得分: 24

另一个选项是使用匿名函数,如下所示:

package main

import "fmt"

func f(c chan func() (int, string)) {
    c <- (func() (int, string) { return 0, "s" })
}

func main() {
    c := make(chan func() (int, string))
    go f(c)
    y, z := <-c()
    fmt.Println(y)
    fmt.Println(z)
}
英文:

Another option would be to use an anon function like so:

package main

import &quot;fmt&quot;

func f(c chan func() (int, string)) {
	c &lt;- (func() (int, string) { return 0, &quot;s&quot; })
}

func main() {
	c := make(chan func() (int, string))
	go f(c)
	y, z := (&lt;-c)()
	fmt.Println(y)
	fmt.Println(z)
}

Credit to https://gist.github.com/slav/ca2ee333c29b8f76b557c9b10b371b52

huangapple
  • 本文由 发表于 2013年7月24日 13:27:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/17825857.html
匿名

发表评论

匿名网友

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

确定