如何用单函数传不同参数创建Cron任务?Go代码仅首尾参数生效怎么解决?
问题原因
这是Go语言for循环迭代变量的经典捕获问题:
- for range循环中的迭代变量
ta是单实例复用的,整个循环周期内ta只会占用一块内存地址,每次迭代仅更新该地址存储的具体值 - 传入
c.AddFunc的匿名函数属于闭包,默认捕获的是ta的内存引用,而非迭代时的瞬时值 - 所有定时任务被调度执行时,for循环早已执行完成,此时
ta存储的是task切片最后一个元素的取值,所有任务执行时都会读取这个最终值,因此仅最后一个参数对应的任务逻辑看起来正常运行。
修复方案
有两种常用的修复方式,任选其一即可:
方案1:循环内声明局部变量缓存当前迭代值
每次循环生成独立的局部变量,闭包捕获不同的局部变量地址,避免取值冲突:
c := cron.New() task := inittask() for _, ta := range task { // 循环内声明的局部变量每次迭代都会生成独立实例 currentTa := ta c.AddFunc("*/10 * * * * *", func() { getdata(currentTa, DBS, DBT) }) } c.Start() select {}
方案2:匿名函数传参拷贝当前值
通过匿名函数入参传递的机制,在注册任务时就把当前ta的值拷贝进闭包:
c := cron.New() task := inittask() for _, ta := range task { // 定义带参数的匿名函数,调用时立即传入当前ta的值完成拷贝 c.AddFunc("*/10 * * * * *", func(t any) { // 此处把any替换为ta变量的实际类型即可 getdata(t, DBS, DBT) }(ta)) } c.Start() select {}
内容的提问来源于stack exchange,提问作者Jiuping.Lee
相关产品推荐
相关产品推荐

