Scopelint エラー: 範囲スコープでの変数の使用
テスト関数 TestGetUID で、コードでscopelint によって報告されるエラーが発生しました。関数リテラル内の範囲スコープから変数 x を使用します。
次のコードを考えてみましょう。行:
for _, x := range tests {
t.Run(x.description, func(t *testing.T) {
client := fake.NewSimpleClientset(x.objs...)
actual := getUID(client, x.namespace)
assert.Equal(t, x.expected, actual)
})
}
x はテスト スライスを反復する範囲ループ内のループ変数であるため、エラーはこれらの行に関係します。 Scopelint は、t.Run() に渡される関数リテラルで x が使用されていることを検出します。これは、t.Run() が返された後に関数リテラルが呼び出された場合に潜在的な問題を引き起こす可能性があります。
原因とベスト プラクティス
この問題は、関数リテラルが作成されて渡されることをコンパイラが保証できないために発生します。 t.Run() が終了した後は、t.Run() は呼び出されません。関数リテラルが t.Run() が戻った後に呼び出された場合、関数リテラルは x 変数を参照します。この変数は、後続のループ反復の値で上書きされている可能性があります。
Go vet はこの警告を生成します。このような意図しない動作を防止します。関数リテラルが異なるゴルーチンで同時に実行されると、バグやデータ競合が発生する可能性があります。
このような場合に推奨されるベスト プラクティスループ変数の値を関数リテラルに引数として渡すか、ループ変数のコピーを作成して関数リテラル内でコピーを参照するかのどちらかです。関数リテラルの署名は変更できないため、推奨される解決策はコピーを作成することです。例:
x2 := x
このコピーを宣言した後、関数リテラルは、ループ変数ではなく、ローカル コピーを参照します。コピーに同じ名前を割り当てるのは混乱するように思えるかもしれませんが、これはコピーを使用する意図を明確に示しています。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3