dongsheng8664 2016-05-30 07:27
浏览 36
已采纳

转到频道将每个字母作为字符串而不是整个字符串

I'm creating a simple channel that takes string values. But apparently I'm pushing each letter in the string instead of the whole string in each loop.

I'm probably missing something very fundamental. What am I doing wrong ?

https://play.golang.org/p/-6E-f7ALbD

Code:

func doStuff(s string, ch chan string) {
    ch <- s
}

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

    for i := 0; i < len(loops); i++ {
        go doStuff("helloooo", c)
    }

    results := <-c

    fmt.Println("channel size = ", len(results))

    // print the items in channel
    for _, r := range results {
        fmt.Println(string(r))
    }
}
  • 写回答

2条回答 默认 最新

  • dongshi1188 2016-05-30 07:34
    关注

    Your code sends strings on the channel properly:

    func doStuff(s string, ch chan string){
        ch <- s
    }
    

    The problem is at the receiver side:

    results := <- c
    
    fmt.Println("channel size = ", len(results))
    
    // print the items in channel
    for _,r := range results {
      fmt.Println(string(r))
    }
    

    results will be a single value received from the channel (the first value sent on it). And you print the length of this string.

    Then you loop over this string (results) using a for range which loops over its runes, and you print those.

    What you want is loop over the values of the channel:

    // print the items in channel
    for s := range c {
        fmt.Println(s)
    }
    

    This when run will result in a runtime panic:

    fatal error: all goroutines are asleep - deadlock!
    

    Because you never close the channel, and a for range on a channel runs until the channel is closed. So you have to close the channel sometime.

    For example let's wait 1 second, then close it:

    go func() {
        time.Sleep(time.Second)
        close(c)
    }()
    

    This way your app will run and quit after 1 second. Try it on the <kbd>Go Playground</kbd>.

    Another, nicer solution is to use sync.WaitGroup: this waits until all goroutines are done doing their work (sending a value on the channel), then it closes the channel (so there is no unnecessary wait / delay).

    var wg = sync.WaitGroup{}
    
    func doStuff(s string, ch chan string) {
        ch <- s
        wg.Done()
    }
    
    // And in main():
    for i := 0; i < len(loops); i++ {
        wg.Add(1)
        go doStuff("helloooo", c)
    }
    go func() {
        wg.Wait()
        close(c)
    }()
    

    Try this one on the <kbd>Go Playground</kbd>.

    Notes:

    To repeat something 5 times, you don't need that ugly loops array. Simply do:

    for i := 0; i < 5; i++ {
        // Do something
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 用hfss做微带贴片阵列天线的时候分析设置有问题
  • ¥50 我撰写的python爬虫爬不了 要爬的网址有反爬机制
  • ¥15 Centos / PETSc / PETGEM
  • ¥15 centos7.9 IPv6端口telnet和端口监控问题
  • ¥120 计算机网络的新校区组网设计
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 海浪数据 南海地区海况数据,波浪数据
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等