【发布时间】:2014-08-05 14:57:21
【问题描述】:
当我在 Go 中编写一个函数时,它应该返回一个值和一个类似的错误
func createHashedPassword(password string) string, error {
//code
}
我想在 goroutine 中执行这个 createHashedPassword,我想通过通道传递数据。
但我的问题是,我该如何处理这里或 goroutine 中的错误?
【问题讨论】:
标签: go
当我在 Go 中编写一个函数时,它应该返回一个值和一个类似的错误
func createHashedPassword(password string) string, error {
//code
}
我想在 goroutine 中执行这个 createHashedPassword,我想通过通道传递数据。
但我的问题是,我该如何处理这里或 goroutine 中的错误?
【问题讨论】:
标签: go
通常将多个输出捆绑到一个结构中,然后通过单个通道将它们一起返回。
type Result struct {
Message string
Error error
}
ch := make(chan Result)
【讨论】:
您可以传入错误通道和结果通道。
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)
}
【讨论】:
这是我的两种首选方式:
两个频道,封装
这是“双通道”的方式,但包装成一个函数,使其看起来类似于常见的模式:
func createHashedPasswordAsynchronously(password string) (chan string, chan error) {
resultCh := make(chan string)
errorCh := make(chan error)
go func(password string) {
//code
if err != nil {
errorCh <- errors.New("Does not compute")
} else {
resultCh <- "8badf00d"
}
}(password)
return resultCh, errorCh
}
并像这样调用:
resultCh, errorCh := createHashedPasswordAsynchronously("mysecret")
select {
case result := <-resultCh:
storeHashedPassword(result)
case err := <-errorCh:
log.Println(err.Error())
}
匿名结构
这是“匿名结构”方式,类似于@saward 的回答,但没有明确命名结构成员:
go func(password string, ch chan struct {
string
error
}) {
//code
if err != nil {
ch <- struct {
string
error
}{"", errors.New("Does not compute")}
} else {
ch <- struct {
string
error
}{"8badf00d", nil}
}
}("mysecret", ch)
r := <-ch
if r.error != nil {
log.Println(r.error.Error())
} else {
storeHashedPassword(r.string)
}
【讨论】:
(因为我还不能评论...)
我附和 JimB 所说的话:
type Result struct {
Message string
Error error
}
ch := make(chan Result)
两个独立通道的问题,一个用于结果,另一个用于错误,是(据我了解)它不支持开箱即用的并发线程。
例如,您可以让两个线程同时发送数据,此时回复会出现乱序。也就是说,你首先收到线程 1 的结果,但首先收到线程 2 的错误。
像 JimB 建议的那样创建新类型很容易,并且应该可以很好地与 goroutines 配合使用。
【讨论】: