建议不要封装不必要的东西,简洁才最好

来源:6-2 使用Channel等待任务结束

springlee

2021-07-29 18:06:05

​本来就是学习,能简单地把重点讲清楚才最重要。还定义新的 type,还是同名,又改函数名真的感觉很累。代码跳来跳去,稍不注意就写得不一样,容易出问题。下面是我实现的,我习惯于把代码放到测试里,这样 ide 里可以单击运行,非常单个方便。

func worker(id int, c chan int, done chan bool){
for data := range c {
fmt.Printf("Worker %d receive %d\n", id, data)

go func(){
done <- true
}()
}
}

func TestChanDone(t *testing.T) {

var channelsIn [10]chan int
var channelsDone[10]chan bool
for i := 0; i < 10; i++ {
channelsIn[i] = make(chan int)
channelsDone[i] = make(chan bool)
go worker(i, channelsIn[i], channelsDone[i]) //定义接收
}

for i, item := range channelsIn {
item <- 'a' + i
}
for i, in := range channelsIn {
in <- 'A' + i
}

for _, done := range channelsDone {
<- done
<- done
}
time.Sleep(time.Millisecond)

}


写回答

1回答

ccmouse

2021-08-03

这里探讨了几个风格问题,风格问题没有对错,我说下我的看法。


首先把代码放在测试里是一个好习惯。我鼓励把这些例子用测试的方式来写。我在后面项目的实现中也会大量的使用测试。测试的问题是对于这些并发的例子,有可能输出是不确定的,当然,根据具体问题也有具体的解决方案。我后面也有如何固定测试输出(结果)的一些做法。


另外不要封装不必要的东西,的确。但这里是需要的。

var channelsIn [10]chan int
var channelsDone[10]chan bool

我们看这两个数组(其实很多竞赛的代码会像同学这么写,更简洁)。为什么它们的大小要相等?为什么每个worker必须对应下标相同的channelsIn以及channelsDone?这两个问题看似很明显但我们是无法通过代码体现出来的,无法自证。


再说下重名的问题。保持名称的一致性很重要。这个一致性是对于“概念 ”的一致性。同一个“概念”,它始终叫同一个名字,我们一开始可能用一个简单的数据类型来描述它,后面可以扩展成复杂的类型,但是名字我们始终保持不变。类型的改变使得我们可以利用编译器来帮助我们“标注”所有上下游需要的改动。这样重构的时候修改多一些,但是代码就不会带有很多的历史包袱。


2

0 学习 · 1399 问题

查看课程