英文:
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 (
"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)
}
}
答案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 "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)
}
Credit to https://gist.github.com/slav/ca2ee333c29b8f76b557c9b10b371b52
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论