【问题标题】:Why do I need to do an additional for loop over the results of my go routine/channel to display all results?为什么我需要对我的 goroutine/channel 的结果进行额外的 for 循环以显示所有结果?
【发布时间】:2018-07-10 16:11:03
【问题描述】:

快速解释代码:

  • 我的范围是 db.Feeds(),这是一个 RSS 提要 url 列表。
  • 我正在通过 goroutine 获取 getFeeds() 函数中的提要
  • getFeeds() 的输出返回到 rss 频道
  • 然后我打印 RSS 信息

    func main() {
        rss := make(chan feed)
    
        for _, url := range db.Feeds() {
            go getFeeds(url, rss)
        }
    
        for range db.Feeds() {
            newFeed := <-rss
            fmt.Println(newFeed.Channel.Title, newFeed.Channel.Description)
        }
    }
    

我的问题如下:当我直接打印 newFeed 变量时,它不会显示来自 rss 通道的所有结果,只显示第一个。

我似乎必须覆盖db.Feeds()(RSS 提要网址列表)并从包含 go getFeeds() 的 for 循环中打印频道结果,以显示所有结果。

为什么会这样?尽管对于范围的每个循环,我都会返回到 rss 通道并打印结果,而不必第二次超过db.Feeds()

任何澄清都有很大帮助,我是 Go 新手!喜欢它,但我还没有理解该语言的某些方面。

【问题讨论】:

    标签: for-loop go concurrency range goroutine


    【解决方案1】:

    &lt;-channel 运算符使用通道中的单个元素。如果您想继续阅读直到通道关闭,您需要覆盖它。

    但是,您需要覆盖频道本身,而不是db.Feeds

    for newFeed := range rss {
        fmt.Println(newFeed.Channel.Title, newFeed.Channel.Description)
    }
    

    从技术上讲,多次重复读取 newFeed := &lt;-rss 才是真正有效的方法。

    目前,这仅适用于您拥有与写入rss 的元素相同数量的提要。相反,如果元素数量不匹配,您要么在读取所有元素之前退出,要么在没有更多元素时等待更多。

    您还需要某种类型的协调,以确保在完成所有 getFeeds 功能后关闭 rss 频道。

    我强烈建议您参加 Go 之旅,尤其是 concurrency section

    【讨论】:

    • 感谢您的解释和提示!
    猜你喜欢
    • 1970-01-01
    • 2021-02-15
    • 2013-10-22
    • 2015-06-17
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多