为了账号安全,请及时绑定邮箱和手机立即绑定

golang字符串通道发送/接收不一致

golang字符串通道发送/接收不一致

Go
泛舟湖上清波郎朗 2021-11-08 19:34:08
新去。我正在使用 1.5.1。我正在尝试根据传入频道累积一个单词列表。但是,我的输入通道 (wdCh) 在测试期间有时会得到空字符串 ("")。我很困惑。在将其累积计数添加到我的地图之前,我宁愿不对空字符串进行测试。对我来说感觉就像一个黑客。package accumulatorimport (    "fmt"    "github.com/stretchr/testify/assert"    "testing")var words map[string]intfunc Accumulate(wdCh chan string, closeCh chan bool) {    words = make(map[string]int)    for {        select {        case word := <-wdCh:            fmt.Printf("word = %s\n", word)            words[word]++        case <-closeCh:            return        }    }}func pushWords(w []string, wdCh chan string) {    for _, value := range w {        fmt.Printf("sending word = %s\n", value)        wdCh <- value    }    close(wdCh)}func TestAccumulate(t *testing.T) {    sendWords := []string{"one", "two", "three", "two"}    wMap := make(map[string]int)    wMap["one"] = 1    wMap["two"] = 2    wMap["three"] = 1    wdCh := make(chan string)    closeCh := make(chan bool)    go Accumulate(wdCh, closeCh)    pushWords(sendWords, wdCh)    closeCh <- true    close(closeCh)    assert.Equal(t, wMap, words)}
查看完整描述

2 回答

?
开心每一天1111

TA贡献1836条经验 获得超13个赞

查看这篇关于channel-axioms 的文章。看起来在关闭wdCh和在closeCh通道上发送 true之间存在竞争。

因此,结果取决于在pushWords返回 和之间首先安排什么Accumulate

如果TestAccumulate首先运行,则发送 true on closeCh,然后在Accumulate运行时它会选择两个通道中的任何一个,因为它们都可以运行,因为pushWordsclosed wdCh

来自关闭通道的接收立即返回零值。

直到closedCh发出信号,Accumulate会在地图中随机放置一个或多个空“”字。

如果Accumulate首先运行,那么它可能会在单词映射中放入许多空字符串,因为它会循环直到TestAccumulate运行并最终在 上发送信号closeCh

一个简单的解决方法是移动

close(wdCh)

发送后truecloseCh。这种方式wdCh不能返回零值,直到您在closeCh. 此外,closeCh <- true块因为closeCh没有缓冲区大小,所以wdCh在你保证Accumulate永远完成循环之前不会关闭。


查看完整回答
反对 回复 2021-11-08
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

我认为原因是当您关闭通道时,“选择”虽然会收到信号。


因此,当您关闭“func pushWords”中的“wdCh”时,Accumulate 中的循环将从“<-wdCh”接收信号。可能是你应该添加一些代码来测试通道关闭后的动作!


for {

    select {

    case word, ok := <-wdCh:

        if !ok {

            fmt.Println("channel wdCh is closed!")

            continue

        }

        fmt.Printf("word = %s\n", word)

        words[word]++

    case <-closeCh:

        return

    }

}


查看完整回答
反对 回复 2021-11-08
  • 2 回答
  • 0 关注
  • 260 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信