循环后,带有范围app的频道会中断

时间:2014-08-09 20:59:06

标签: go

我有一个问题,我的应用程序在循环通道后不会到达下一个语句。为了澄清,我的意思是,请查看以下代码段。

func CreateAccount(name, email, password string) (string, string) {

    validation := make(chan error)
    errColl := make([]error, 3, 3)
    iterator := 0

    go func() {
        nameErr := IsNameValid(name)
        validation <- nameErr
    }()

    go func() {
        emailErr := IsEmailValid(email)
        validation <- emailErr

    }()

    go func() {
        passwordErr := IsPasswordValid(password)
        validation <- passwordErr
    }()

    for err := range validation {
        errColl[iterator] = err
        iterator++
    }
    fmt.Println("Hello")


    return "hello", "dude"

}

这是我的创建帐户功能。在三个goroutine之后,我在通道验证上做了一个循环。循环完成后,语句

  

fmt.Println(&#34;你好)

永远不会执行。但是当我改变这样的功能时。

func CreateAccount(name, email, password string) (string, string) {

    validation := make(chan error)
    errColl := make([]error, 3, 3)
    //iterator := 0

    go func() {
        nameErr := IsNameValid(name)
        validation <- nameErr
    }()

    go func() {
        emailErr := IsEmailValid(email)
        validation <- emailErr

    }()

    go func() {
        passwordErr := IsPasswordValid(password)
        validation <- passwordErr
    }()

    errColl[0] = <-validation
    errColl[1] = <-validation
    errColl[2] = <-validation
    close(validation)
    fmt.Println("Hello")

    return "hello", "dude"

}

你好打印出来,加上我得到了返回值 我在第一段代码中出了什么问题?

2 个答案:

答案 0 :(得分:7)

永远不会关闭validation频道。

for err := range validation {
    errColl[iterator] = err
    iterator++
}
  

The Go Programming Language Specification

     

For statements

     

A&#34; for&#34;声明带有&#34;范围&#34;子句遍历所有条目   数组,切片,字符串或映射,或在通道上接收的值。

     

对于通道,生成的迭代值是连续值   发送到频道,直到频道关闭。

答案 1 :(得分:4)

就像@peterSO所说,你没有关闭频道,这种模式的正确方法是使用sync.WaitGroup

func CreateAccount(name, email, password string) (string, string) {
    var wg sync.WaitGroup
    validation := make(chan error, 3)
    errColl := make([]error, 3)

    wg.Add(3)
    go func() {
        nameErr := IsNameValid(name)
        validation <- nameErr
        wg.Done()
    }()

    go func() {
        emailErr := IsEmailValid(email)
        validation <- emailErr
        wg.Done()

    }()

    go func() {
        passwordErr := IsPasswordValid(password)
        validation <- passwordErr
        wg.Done()
    }()
    wg.Wait()
    for i := range errColl {
        errColl[i] = <-validation
    }

    return "hello", "dude"

}