【问题标题】:Error "too many variables in range" when iterating over a channel遍历通道时出错“范围内的变量太多”
【发布时间】:2018-11-24 11:22:17
【问题描述】:

我有点迷路了,我试图让一个 goroutine 添加到数组和另一个 goroutine 从中读取,我怀疑它有点接近我下面的内容,但我需要玩弄等待()。

但是,我收到错误 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-loop go channel


    【解决方案1】:

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

    所以你必须使用:

    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
    

    【讨论】:

    • 所以即使使用_,它仍然期望返回该值,即使它会被丢弃?
    • @Derek 是的,如果您指定空白标识符,这意味着您在每次迭代中期望 2 个值,但跨通道仅产生 1 个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 2017-05-25
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 1970-01-01
    • 2020-12-10
    相关资源
    最近更新 更多