簡體   English   中英

在通道上迭代時出錯“范圍內的變量太多”

[英]Error "too many variables in range" when iterating over a channel

我有點迷路了,我試圖讓一個 goroutine 添加到一個數組中,另一個 goroutine 從中讀取,我懷疑它有點接近我下面的內容,但我需要使用 wait() .

但是,我收到錯誤prog.go:19:14: too many variables in range ,第 19 行是for _, v := range c {我在網上找不到答案,我在做什么在這里做什么?

package main

import (
    "fmt"
    //"time"
    "sync"
)

func hello(wg *sync.WaitGroup, s []int, c chan int) {
    for _, v := range s {
        c <- v
    }
    fmt.Println("Finished adding to channel")
    wg.Done()
}

func hello2(wg *sync.WaitGroup, c chan int) {
    fmt.Println("Channel",c)
    for _, v := range c {
        fmt.Println("Received",v)   
    }
    fmt.Println("Finished taking from channel")
    wg.Done()
}

func main() {
    s := []int{1, 2, 3, 4, 5}
    var c = make(chan int, 5)


    var wg sync.WaitGroup
    wg.Add(1)
    go hello(&wg, s, c)
    wg.Wait()
    wg.Add(1)
    go hello2(&wg, c)
    wg.Wait()
    //time.Sleep(1 * time.Second)
    fmt.Println("main function")
}

當您在通道上進行范圍時,迭代只會產生一個值,即在通道上發送的值。 沒有像切片或映射那樣的索引或鍵值。

所以你必須使用:

for v := range c {
    fmt.Println("Received", v)   
}

這在規格中有詳細說明:對於語句:

如果范圍表達式是通道,則最多允許一個迭代變量,否則最多可以有兩個。

和:

對於通道,產生的迭代值是通道上發送的連續值,直到通道關閉 如果通道為nil ,則范圍表達式將永遠阻塞。

並且:

左側的函數調用在每次迭代時評估一次。 對於每次迭代,如果存在相應的迭代變量,則按如下方式生成迭代值:

 Range expression 1st value 2nd value array or slice a [n]E, *[n]E, or []E index i int a[i] E string s string type index i int see below rune map m map[K]V key k K m[k] V channel c chan E, <-chan E element e E

我知道您不打算/希望為范圍循環的通道使用迭代器,但是如果您確實希望有一個迭代器,仍然可以通過在循環之外自己定義迭代器並在每次有值時遞增它通道被讀取。

    var wg sync.WaitGroup
    var iterator = 0
    for v := range c1 {
        wg.Add(1)
        iterator += 1
        go func(v2, i2 int) {
            c2 <- timeConsumingWork(v2)
            fmt.Println("item ", i2, " done")
            wg.Done()
        }(v, iterator)
    }
    wg.Wait()
    close(c2)

}

在這里您可以看到 go func 正在接受通道值(v2)和迭代器值(i2),同時每次從通道中讀取值時遞增它。

此外,我看到您使用緩沖的等待組來避免因順序調用您的兩個方法而阻塞。 理想的 Go 代碼應該盡可能避免使用緩沖通道,而是以互鎖的方式調用發送和接收函數,這樣它們就不需要分開了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM