Go 从通道返回错误

Go 从通道返回错误,go,Go,当我在Go中编写函数时,它应该返回一个值和一个错误,如 func createHashedPassword(password string) string, error { //code } 我想在goroutine中执行这个createHashedPassword,我想通过通道传递数据。 但我的问题是,我如何处理这里或goroutine中的错误?您可以传入错误通道和结果通道 errors := make(chan error, 0) results := make(chan stri

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

func createHashedPassword(password string) string, error {
    //code
}
我想在goroutine中执行这个createHashedPassword,我想通过通道传递数据。

但我的问题是,我如何处理这里或goroutine中的错误?

您可以传入错误通道和结果通道

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)
}
错误:=make(chan错误,0)
结果:=make(chan字符串,0)
密码:=“测试”
go func(){
结果,错误:=createHashedPassword(字符串密码)
如果错误!=零{

错误通常将多个输出捆绑到一个结构中,然后通过单个通道将它们一起返回

type Result struct {
    Message string
    Error error
}

ch := make(chan Result)
(因为我还不能评论…)

我附和吉米的话:

type Result struct {
    Message string
    Error error
}

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

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


像JimB建议的那样创建新类型很容易,并且应该与goroutines配合使用。

以下是我喜欢的两种方法:

两个频道,已包装

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

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
}
func异步创建hashedpassword(密码字符串)(chan字符串,chan错误){
结果:=make(chan字符串)
errorCh:=制造(更改错误)
go func(密码字符串){
//代码
如果错误!=零{

错误我在这里传递引用类型对吗?我在某个地方读过,当可以避免通过通道传递引用类型时,这是真的吗?这是错误的,你是指指针吗?没有官方的“引用类型”概念,但切片和贴图通常称为“引用类型”。您可以通过一个频道传递任何您想要的内容,其语义与任何其他呼叫或分配相同。围棋流行语是“不要通过共享内存进行通信;相反,通过通信共享内存”.Channels为您提供了一种在线程之间进行通信的方法,而无需防止同时访问同一内存。因此,您可以共享一个指针,但是(如果我理解正确的话)这样做的方式意味着不会有两个或多个线程同时访问该内存。一个线程可以接收指针,对其指向的内存进行操作,然后停止操作并通过通道传递该指针。在任何给定时间,只有一个线程在该指针上工作。
resultCh, errorCh := createHashedPasswordAsynchronously("mysecret")
select {
case result := <-resultCh:
    storeHashedPassword(result)
case err := <-errorCh:
    log.Println(err.Error())
}
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)
}