errors := make(chan error, 0)
results := make(chan string, 0)
password := "test"
go func() {
result, err := createHashedPassword(string password)
if err != nil {
errors <- err
return
}
results <- result
}()
// do something else
// When you are ready to read from goroutine do this:
select {
case err := <- errors:
println(err)
case res := <- results:
println(res)
}
type Result struct {
err error
msg *string // in cases that empty string can be a true result, you can evaluate msg with nil
}
我还应该提到,在某些特殊情况下,我们不返回错误,而只是将其记录在那里。
package main
import (
"fmt"
"log"
)
func main() {
password := "blah blah"
resultChan := make(chan string)
go createHashedPassword(password, resultChan)
// Do some other stuff
fmt.Println(<-resultChan) // Be careful that it's a blocking code.
}
func createHashedPassword(password string, resultChan chan string) {
// your code for hashing and stuff
if err != nil {
log.Println(err) // *** Here we just log the error, or handle it.
}
resultChan <- result
}
5条答案
按热度按时间s6fujrry1#
通常将多个输出捆绑到一个结构体中,并通过单个通道将它们一起返回。
s8vozzvw2#
可以传入错误通道和结果通道。
fd3cxomn3#
以下是我的两种首选方法:
两个声道,环绕
这是“两个通道”的方式,但 Package 成一个函数,使其看起来类似于常见模式:
然后这样叫:
匿名结构
这是一种“匿名结构体”的方式,类似于@saward的答案,但没有显式地命名结构体成员:
omhiaaxx4#
(因为我还不能发表评论...)
我附和JimB的话:
两个独立通道(一个用于结果,另一个用于错误)的问题在于(据我所知)它不支持开箱即用的并发线程。
例如,您可能有两个线程同时发送数据,但回复的顺序不对,也就是说,您首先从线程1接收结果,但首先从线程2接收错误。
像JimB建议的那样创建新类型很容易,而且应该可以很好地与goroutine一起工作。
b5lpy0ml5#
常见模式之一是将错误通道和结果通道传递给函数:
您还可以在
createHashedPassword
内部创建通道,如AndreKR所述,或者在匿名goroutine中调用
createHashedPassword
,就像Ian Davis所说的那样。还有一些其他可能的模式,您可以合并combined struct组合其中的任何一种模式:
或
我还应该提到,在某些特殊情况下,我们不返回错误,而只是将其记录在那里。