for ループの匿名関数に変数を代入できない: クロージャの落とし穴
go-lang を勉強しているときに、開発中に問題が発生しました。 cronライブラリを使用したタスクスケジューラ。スケジューラが、スケジュールされたすべてのジョブの最後のジョブの説明を出力していることがわかりました。この動作は、for ループ内での匿名関数の使用によって引き起こされ、クロージャーの落とし穴につながります。
Go では、for ループ内の val 変数は各スライス要素の値を受け取ります。ループ内でクロージャを使用すると、すべてのクロージャが同じ変数にバインドされます。ゴルーチンはループが終了するまで実行されない可能性が高いため、最後の要素を複数回出力することになります。
この問題を解決するために、ジョブをパラメータとして匿名関数に渡そうとしました。ただし、cron ライブラリは、func() の関数タイプを想定しているため、パラメーターを持つ関数を受け入れません。
推奨される解決策は、ループの反復ごとに新しい変数を作成することです。現在のジョブを新しい変数 (realJob) に割り当てることで、クロージャの新しいスコープを作成し、各クロージャがジョブ変数の独自のインスタンスを持つようにします。
修正されたコードは次のとおりです:
for _, job := range config.Jobs { realJob := job c.AddFunc("@every "+realJob.Interval, func() { DistributeJob(realJob) }) log.Println("Job " + realJob.Name + " has been scheduled!") }
各ループ反復内で新しい realJob 変数を作成することで、クロージャの落とし穴を回避し、スケジュールされた各ジョブで正しい説明が印刷されるようにします。
以上がGo Cron スケジューラがすべてのジョブの最後のジョブの説明を出力するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。