Golang中robfig/cron的AddFunc添加定时任务无法动态执行问题
问题原因
这不是robfig/cron库的bug,属于Go语言的常见闭包变量捕获问题。for range循环中迭代使用的integ、spell是全局复用的变量,每轮循环只会更新这两个变量内存地址对应的值。你在AddFunc中传入的闭包直接引用了这两个变量的地址,没有捕获当前轮次的具体值,等到循环结束、定时任务触发执行时,所有闭包读取到的都是这两个变量最终的迭代值(也就是3和three),所以才会出现全量输出相同内容的情况。
解决方案
两种实现方式都可以达到你预期的输出效果:
- 方案1:循环内新建局部变量存储当前轮次的值
mapp := map[int]string{1: "one", 2: "two", 3: "three"} cr := cron.New() for integ, spell := range mapp { // 新建局部变量拷贝当前轮次的迭代值,每个闭包会捕获各自的局部变量 integ, spell := integ, spell cr.AddFunc("@every 2s", func() { fmt.Println("Running Cron Spell:", spell, "Integer:",integ) }) } cr.Start()
- 方案2:通过匿名函数参数传值捕获当前轮次的内容
mapp := map[int]string{1: "one", 2: "two", 3: "three"} cr := cron.New() for integ, spell := range mapp { // 把当前轮次的值作为参数传入匿名函数,值传递会直接拷贝当前值,不受后续迭代影响 cr.AddFunc("@every 2s", func(integ int, spell string) func() { return func() { fmt.Println("Running Cron Spell:", spell, "Integer:",integ) } }(integ, spell)) } cr.Start()
内容的提问来源于stack exchange,提问作者Mohamad Arafat
相关产品推荐
相关产品推荐

