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 關注
- 231 瀏覽
添加回答
舉報