ホームページ >バックエンド開発 >Golang >## Scopelint エラー: 範囲スコープでの変数の使用 - 関数リテラルでループ変数を安全に参照するにはどうすればよいですか?

## Scopelint エラー: 範囲スコープでの変数の使用 - 関数リテラルでループ変数を安全に参照するにはどうすればよいですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-10-26 02:18:02235ブラウズ

## Scopelint Error: Using Variable on Range Scope - How to Safely Refer to Loop Variables in Function Literals?

Scopelint エラー: 範囲スコープでの変数の使用

テスト関数 TestGetUID で、コードでscopelint によって報告されるエラーが発生しました。関数リテラル内の範囲スコープの変数 x を使用します。

次のコード行を考えてください:

<code class="go">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)
    })
}</code>

x は反復する範囲ループ内のループ変数であるため、エラーはこれらの行に関係します。テストスライスの上に。 Scopelint は、t.Run() に渡される関数リテラルで x が使用されていることを検出します。これは、t.Run() が返された後に関数リテラルが呼び出された場合に潜在的な問題を引き起こす可能性があります。

原因とベスト プラクティス

この問題は、作成されて t.Run() に渡された関数リテラルが t.Run() の終了後に呼び出されないことをコンパイラが保証できないために発生します。関数リテラルが t.Run() が戻った後に呼び出された場合、関数リテラルは x 変数を参照します。この変数は、後続のループ反復の値で上書きされている可能性があります。

Go vet はこの警告を生成します。このような意図しない動作を防ぐには、関数リテラルが異なるゴルーチンで同時に実行されると、バグやデータ競合が発生する可能性があります。

このような場合に推奨されるベスト プラクティスは、 を渡すことです。ループ変数を引数として関数リテラルに追加するか、ループ変数のコピーを作成し、関数リテラル内でコピーを参照します。関数リテラルの署名は変更できないため、推奨される解決策はコピーを作成することです。たとえば、

<code class="go">x2 := x</code>

このコピーを宣言した後、関数リテラル内の x 識別子は、ローカル コピーではなく、ローカル コピーを参照します。ループ変数。コピーに同じ名前を割り当てるのは紛らわしいように思えるかもしれませんが、これはコピーを使用する意図を明確に示しています。

以上が## Scopelint エラー: 範囲スコープでの変数の使用 - 関数リテラルでループ変数を安全に参照するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。