Golang变量中两个持续时间的乘积为零

时间:2016-03-05 08:31:26

标签: time go

在Golang代码中,两个持续时间的乘积在变量'延迟'中是奇怪的,但是当不通过任何变量直接打印产品时,输出是预期的。有谁能解释一下?

 func StartCleanTask() {
  go func() {
       delay := cfg.Config.Timeout * time.Second
       for {
           fmt.Println("Go clean task: ", delay, cfg.Config.Timeout*time.Second)
           select {
           case <-time.After(cfg.Config.Timeout * time.Second):
               clean()
           }
     }
  }()

}

输出结果为:

 Go clean task: 0 5m0s

更新

我还尝试运行以下代码,效果很好。

package main 
import "fmt"
import "time"

func main() {

   var timeout time.Duration
   timeout = 100
   delay := timeout * time.Second

   fmt.Println("Go clean task: ", delay, timeout*time.Second)

}

再次更新:

保罗的回答被接受了。实际上,在cfg包的init函数中调用StartCleanTask(),并将cfg.Config.Timeout分配给main函数中的指定值。但是我忽略了在main()之前隐式调用了包的init()函数,因此变量delay总是为零。

顺便说一句,我不明白为什么有些人会对这个问题给出负面评分。我认为其他人可能遇到类似的问题,这篇文章应该对那些不太了解init()和main()之间的调用顺序的受害者有所帮助。

1 个答案:

答案 0 :(得分:2)

我的猜测是你正在同时更新cfg.Config.Timeout这项任务。也许是这样的:

func main() {
    StartCleanTask()
    cfg.Config.Timeout = 300
    ...
}

这引入了一场比赛,并且在StartCleanTask内的goroutine中,delay在初始化Timeout之前被分配,并且fmt.Println在初始化之后发生

您可以使用race detector查看这是否是问题。

假设cfg仅初始化一次,可能正确的修复只是在初始化完成后才启动清理任务。