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

在下面的 Golang 代码中奇怪的是,变量 'delay' 中两个持续时间的乘积为零,但是当不通过任何变量直接打印乘积时,输出符合预期。任何人都可以解释这一点?


 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)


}

再次更新:


保罗的回答被接受。实际上StartCleanTask()是在cfg包的init函数中调用的,cfg.Config.Timeout在main函数中被赋值为一个指定的值。但是我忽略了该包的 init() 函数在 main() 之前隐式调用,因此变量延迟始终为零。


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


慕雪6442864
浏览 141回答 1
1回答

拉丁的传说

我的猜测是您正在cfg.Config.Timeout同时更新此任务。也许像这样:func main() {&nbsp; &nbsp; StartCleanTask()&nbsp; &nbsp; cfg.Config.Timeout = 300&nbsp; &nbsp; ...}这就引入了一个竞争,恰好在 goroutine 里面StartCleanTask,delay在Timeout初始化之前被赋值,而fmt.Println在初始化之后发生。您可以使用竞态检测器来查看这是否是问题所在。假设cfg只初始化一次,可能正确的解决方法是在初始化完成后才启动清理任务。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go