tee-channel
最后更新于:2022-04-02 06:51:20
有时候你可能想分割来自通道的多个值,以便将它们发送到两个独立区域。想象一下:你可能想要在一个通道上接收一系列操作指令,将它们发送给执行者,同时记录操作日志。
与Unix系统的tee命令功能类似,我们用tee-channel来实现同样的功能。你可以传递给它一个用作读取的通道,它会返回两个单独的通道:
```
tee := func(
done <-chan interface{},
in <-chan interface{},
) (_, _ <-chan interface{}) { <-chan interface{}) {
out1 := make(chan interface{})
out2 := make(chan interface{})
go func() {
defer close(out1)
defer close(out2)
for val := range orDone(done, in) {
var out1, out2 = out1, out2 //1
for i := 0; i < 2; i++ { //2
select {
case <-done:
case out1 <- val:
out1 = nil //3
case out2 <- val:
out2 = nil //3
}
}
}
}()
return out1, out2
}
```
***注意:原文例子就是这样,反复确认没有贴错。大家就当伪码看吧***
1. 我们希望使用使用本地的变量,所以建立了他们的副本。
2. 我们将使用一条select语句,以便写入out1和out2不会彼此阻塞。 为了确保两者都顺利写入,我们将执行select语句的两个迭代。
3. 一旦我们写入了通道,我们将其副本设置为零,这样继续写入将阻塞,而另一个通道可以继续执行。
注意写入out1和out2是紧密耦合的。 直到out1和out2都被写入,迭代才能继续。 通常这不是问题,因为无论如何,处理来自每个通道的读取流程的吞吐量应该是tee之外的关注点,但值得注意。 这是一个快速调用示例:
```
done := make(chan interface{})
defer close(done)
out1, out2 := tee(done, take(done, repeat(done, 1, 2), 4))
for val1 := range out1 {
fmt.Printf("out1: %v, out2: %v\n", val1, <-out2)
}
```
利用这种模式,很容易使用通道作为系统数据的连接点。
* * * * *
学识浅薄,错误在所难免。我是长风,欢迎来Golang中国的群(211938256)就本书提出修改意见。
';