从频道返回错误

时间:2014-08-05 14:57:21

标签: go

当我在Go中编写一个函数时,它应该返回一个值和一个错误,如

func createHashedPassword(password string) string, error {
    //code
}

我想在goroutine中执行这个createHashedPassword,我想通过频道传递数据。
但我的问题是,我如何在这里或在goroutine中处理错误?

4 个答案:

答案 0 :(得分:35)

将多个输出捆绑到结构中是很常见的,并通过单个通道将它们一起返回。

type Result struct {
    Message string
    Error error
}

ch := make(chan Result)

答案 1 :(得分:16)

您可以传入错误频道和结果频道。

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)
}

答案 2 :(得分:8)

以下是我的两种首选方式:

两个频道,包裹

这是“两个通道”的方式,但包装成一个函数,使其看起来类似于常见的模式:

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)
}

答案 3 :(得分:4)

(因为我还不能发表评论......)

我回应JimB所说的话:

type Result struct {
    Message string
    Error error
}

ch := make(chan Result)

两个独立通道的问题,一个用于结果,另一个用于错误,是(据我所知),它不支持开箱即用的并发线程。

例如,您可以有两个线程同时发送数据,其中回复无序。也就是说,首先从线程1接收结果,但首先从线程2接收错误。

很容易创建像JimB建议的新类型,并且应该与goroutines一起使用。