2 回答
TA贡献1844条经验 获得超8个赞
你是对的,股票的通道没有在停止时关闭,这是在文档中说明的:
停止关闭自动收报机。停止后,将不再发送报价单。停止不会关闭通道,以防止从通道读取不正确地成功。
我相信自动收报机更多的是关于火和忘记,即使你想阻止它,你甚至可以永远挂起例行程序(当然取决于你的应用程序)。
如果你真的需要一个有限的股票代码,你可以做一些技巧并提供一个单独的频道(根据 ThunderCat 的回答),但我要做的是提供我自己的股票代码实现。这应该相对容易,并且会为您提供其行为的灵活性,例如在通道上传递什么或决定如何处理丢失的滴答声(即当读者落后时)。
我的例子:
func finiteTicker(n int, d time.Duration) <-chan time.Time {
ch := make(chan time.Time, 1)
go func() {
for i := 0; i < n; i++ {
time.Sleep(d)
ch <- time.Now()
}
close(ch)
}()
return ch
}
func main() {
for range finiteTicker(10, 100*time.Millisecond) {
fmt.Println("hi")
}
}
http://play.golang.org/p/ZOwJlM8rDm
TA贡献1811条经验 获得超6个赞
我也在 IRC 上问过,从@Tv` 那里得到了一些有用的见解。
尽管timer.Ticker看起来它应该是 go pipeline 的一部分,但它实际上并不能很好地与管道习语配合使用:
以下是管道建设指南:
当所有发送操作完成后,stage 关闭它们的出站通道。
阶段不断从入站通道接收值,直到这些通道关闭或发送方被解除阻塞。
管道通过确保所有发送的值有足够的缓冲区或在接收方可能放弃通道时明确通知发送方来解除对发送方的阻塞。
这种不一致的原因似乎主要是为了支持以下习语:
for {
select {
case <-ticker.C:
// do something
case <-done:
return
}
}
我不知道为什么会这样,以及为什么没有使用流水线习语:
for {
select {
case _, ok := <-ticker.C:
if ok {
// do something
} else {
return
}
}
}
(或更干净)
for _ = range ticker.C {
// do something
}
但这是要走的路:(
- 2 回答
- 0 关注
- 205 浏览
添加回答
举报