GO 频道突然结束?

GO Channels ending abruptly?

我正在尝试使用 go channels 同时生成帐户(下面是简化的代码),但是我发现它没有生成所有帐户:

package main

import (
    "fmt"
    "github.com/segmentio/ksuid"
)

const ConcurrencyLevel = 10

const TotalAccounts = 30

type (
    Accounts []Account

     Account struct {
        AccountID   string
    }
)

func GenerateRandomAccountID() (accountReferenceID string){
    return ksuid.New().String()
}

func main() {
    totalAccounts := make(Accounts, 0, TotalAccounts)
    total := 0
    for total < TotalAccounts {
        accounts := make([]Account, ConcurrencyLevel)
        ch := make(chan Account)
        for range accounts {
            go func() {
                accountID := GenerateRandomAccountID()
                account := Account{AccountID: accountID}
                ch <- account
            }()
        }

        for k, _ := range accounts {
            account := <-ch
            accounts[k] = account
        }
        totalAccounts = append(totalAccounts, accounts...)
        total += len(totalAccounts)
        close(ch)
    }
    fmt.Printf("total is : %d\n", total)
    fmt.Printf("total accounts generated is : %d\n", len(totalAccounts))

}

打印出来

total is : 30
total accounts generated is : 20

预计在这种情况下生成的帐户总数为 30。

https://go.dev/play/p/UtFhE2nidaP

你的逻辑有误:

totalAccounts = append(totalAccounts, accounts...)
total += len(totalAccounts)

假设这是循环的第二次迭代。 totalAccounts 已经包含 10 个项目,你再添加 10 个,所以长度现在是 20。然后你取 total(从第一个 运行 到 10)并添加 len(totalAccounts) (20) 给出 30 的结果。这意味着您的循环 (for total < TotalAccounts) 完成时间早于应有的时间。

要解决此问题,您可以使用 playground:

totalAccounts = append(totalAccounts, accounts...)
total += len(accounts) // Add the number of NEW accounts

totalAccounts = append(totalAccounts, accounts...)
total = len(totalAccounts ) // = not +=