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

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

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.

  1. func CreateAccount(name, email, password string) (string, string) {
  2. validation := make(chan error)
  3. errColl := make([]error, 3, 3)
  4. iterator := 0
  5. go func() {
  6. nameErr := IsNameValid(name)
  7. validation <- nameErr
  8. }()
  9. go func() {
  10. emailErr := IsEmailValid(email)
  11. validation <- emailErr
  12. }()
  13. go func() {
  14. passwordErr := IsPasswordValid(password)
  15. validation <- passwordErr
  16. }()
  17. for err := range validation {
  18. errColl[iterator] = err
  19. iterator++
  20. }
  21. fmt.Println("Hello")
  22. return "hello", "dude"
  23. }

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.

  1. func CreateAccount(name, email, password string) (string, string) {
  2. validation := make(chan error)
  3. errColl := make([]error, 3, 3)
  4. //iterator := 0
  5. go func() {
  6. nameErr := IsNameValid(name)
  7. validation <- nameErr
  8. }()
  9. go func() {
  10. emailErr := IsEmailValid(email)
  11. validation <- emailErr
  12. }()
  13. go func() {
  14. passwordErr := IsPasswordValid(password)
  15. validation <- passwordErr
  16. }()
  17. errColl[0] = <-validation
  18. errColl[1] = <-validation
  19. errColl[2] = <-validation
  20. close(validation)
  21. fmt.Println("Hello")
  22. return "hello", "dude"
  23. }

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通道从未关闭。

  1. for err := range validation {
  2. errColl[iterator] = err
  3. iterator++
  4. }

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

英文:

The validation channel is never closed.

  1. for err := range validation {
  2. errColl[iterator] = err
  3. iterator++
  4. }

> 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

  1. func CreateAccount(name, email, password string) (string, string) {
  2. var wg sync.WaitGroup
  3. validation := make(chan error, 3)
  4. errColl := make([]error, 3)
  5. wg.Add(3)
  6. go func() {
  7. nameErr := IsNameValid(name)
  8. validation <- nameErr
  9. wg.Done()
  10. }()
  11. go func() {
  12. emailErr := IsEmailValid(email)
  13. validation <- emailErr
  14. wg.Done()
  15. }()
  16. go func() {
  17. passwordErr := IsPasswordValid(password)
  18. validation <- passwordErr
  19. wg.Done()
  20. }()
  21. wg.Wait()
  22. for i := range errColl {
  23. errColl[i] = <-validation
  24. }
  25. return "hello", "dude"
  26. }
英文:

Like @peterSO said, you didn't close the channel, the proper way for that pattern is to use a sync.WaitGroup:

  1. func CreateAccount(name, email, password string) (string, string) {
  2. var wg sync.WaitGroup
  3. validation := make(chan error, 3)
  4. errColl := make([]error, 3)
  5. wg.Add(3)
  6. go func() {
  7. nameErr := IsNameValid(name)
  8. validation &lt;- nameErr
  9. wg.Done()
  10. }()
  11. go func() {
  12. emailErr := IsEmailValid(email)
  13. validation &lt;- emailErr
  14. wg.Done()
  15. }()
  16. go func() {
  17. passwordErr := IsPasswordValid(password)
  18. validation &lt;- passwordErr
  19. wg.Done()
  20. }()
  21. wg.Wait()
  22. for i := range errColl {
  23. errColl[i] = &lt;-validation
  24. }
  25. return &quot;hello&quot;, &quot;dude&quot;
  26. }

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:

确定