英文:
Never ending Ticker in Golang works only 2 times
问题
我正在尝试创建一个具有无限滚动的频道,但它只工作了两次。
你能帮我理解问题出在哪里吗?
代码:
package main
import (
"fmt"
"time"
)
var mark = [2]float64{8.9876, 762.098568}
func tick(out chan<- [2]float64){
c := time.NewTicker(time.Millisecond *500)
for range c.C{
out <- mark
}
}
func main() {
fmt.Println("Start")
md := make(chan [2]float64)
go tick(md)
for range md{
fmt.Println(<-md)
}
}
输出:
Start
[8.9876 762.098568]
[8.9876 762.098568]
示例:https://play.golang.org/p/P2FaUwbW-3
英文:
I'm trying to make a channel with never ending ticker, but it works only 2 times.
Could you help me to understand where is the problem?
Code:
package main
import (
"fmt"
"time"
)
var mark = [2]float64{8.9876, 762.098568}
func tick(out chan <- [2]float64){
c := time.NewTicker(time.Millisecond *500)
for range c.C{
out <- mark
}
}
func main() {
fmt.Println("Start")
md := make(chan [2]float64)
go tick(md)
for range <-md{
fmt.Println(<-md)
}
}
Output:
Start
[8.9876 762.098568]
[8.9876 762.098568]
Example: https://play.golang.org/p/P2FaUwbW-3
答案1
得分: 9
这段代码:
for range <-md{
与这段代码:
for range md{
不同。后者遍历通道(你想要的),而前者遍历的是循环开始时从通道接收到的值,这个值恰好是一个包含两个元素的数组,所以会执行两次。你还忽略了for
语句中从通道接收到的值,并在循环体中再次从通道中读取值,忽略了通道上的每条其他消息(尽管在这个示例中没有区别,因为每个值都是相同的,但在实际情况下会有很大的区别)。你真正想要的是:
for foo := range md{
fmt.Println(foo)
}
这是一个经过修改的可以正常工作的playground示例,稍作修改以避免出现“程序运行时间过长”的错误,因为在当前形式下它永远不会停止:https://play.golang.org/p/RSUJFvluU5
英文:
This:
for range <-md{
is not the same as:
for range md{
The latter ranges over the channel (what you want), while the former ranges over the value received from the channel when the loop starts, which happens to be a two-element array, hence the two executions. You're also ignoring the value received from the channel in the for
statement, and reading from it again in the loop body, ignoring every other message on the channel (though this makes no difference in the example, since every value is identical, it would make a significant difference in practice). What you really want is:
for foo := range md{
fmt.Println(foo)
}
Here's a working version of your playground example, slightly modified to avoid "program took too long" errors because in its current form it never stops: https://play.golang.org/p/RSUJFvluU5
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论