循环一个范围应用程序中断后的通道。

huangapple go评论89阅读模式
英文:

After loop a channel with range app break

问题

我有一个问题,就是我的应用程序在循环遍历通道后不会执行下一个语句。为了澄清我的意思,看一下下面的代码片段。

这是我的创建账户函数。在三个goroutine之后,我对通道validation进行了循环遍历。循环结束后,语句

fmt.Println("Hello")

永远不会执行。但是当我将函数改成这样时。

Hello将被打印出来,并且我得到了返回值。
在第一个代码片段中,我做错了什么?

英文:

I have a problem, that my application is not going to reach the next statement after loop over a channel. To clarify, what I mean, look at the following code snippet.

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"

}

That is my create account function. After three goroutine, i make a loop over channel validation. After loop is done, the statement

> fmt.Println("Hello)

is never going the execute. But when I change the function like this.

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"

}

Hello is going to printed out and plus I got the return value.
What do I wrong in the first code snippet?

答案1

得分: 7

validation通道从未关闭。

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

> Go编程语言规范
>
> for语句
>
> 带有"range"子句的"for"语句遍历数组、切片、字符串或映射的所有条目,或者接收到的通道值。
>
> 对于通道,生成的迭代值是在通道上发送的连续值,直到通道关闭为止。

英文:

The validation channel is never closed.

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

> The Go Programming Language Specification
>
> For statements
>
> A "for" statement with a "range" clause iterates through all entries
> of an array, slice, string or map, or values received on a channel.
>
> For channels, the iteration values produced are the successive values
> sent on the channel until the channel is closed.

答案2

得分: 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"

}
英文:

Like @peterSO said, you didn't close the channel, the proper way for that pattern is to use a 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 &lt;- nameErr
		wg.Done()
	}()

	go func() {
		emailErr := IsEmailValid(email)
		validation &lt;- emailErr
		wg.Done()

	}()

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

	return &quot;hello&quot;, &quot;dude&quot;

}

huangapple
  • 本文由 发表于 2014年8月10日 04:59:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/25222987.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定