代码之家  ›  专栏  ›  技术社区  ›  Naguib Ihab

在通道上迭代时出现错误“范围内变量太多”

  •  -2
  • Naguib Ihab  · 技术社区  · 6 年前

    我在这里有点迷路了,我试图让一个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")
    }
    
    1 回复  |  直到 6 年前
        1
  •  6
  •   icza    6 年前

    当您在一个通道上设置范围时,迭代只产生一个值,即通道上发送的值。没有索引或键值,就像切片或映射那样。

    所以你必须使用:

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

    详见 Spec: For statements:

    如果范围表达式是通道,则最多允许一个迭代变量 ,否则可能最多有两个。

    还有:

    对于通道,产生的迭代值是通道上发送的连续值,直到通道 closed . 如果频道是 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