ホームページ  >  記事  >  バックエンド開発  >  Go で「関数リテラル (scopelint) で範囲スコープ x の変数を使用する」問題に対処する方法は?

Go で「関数リテラル (scopelint) で範囲スコープ x の変数を使用する」問題に対処する方法は?

Linda Hamilton
Linda Hamiltonオリジナル
2024-10-26 23:24:30642ブラウズ

How to Address

関数リテラルでの範囲変数の使用 (scopelint)

Go では、関数リテラルを定義して高階関数に渡すのが一般的です。ただし、関数リテラル内で範囲変数を使用すると、変数のスコープに関する懸念が生じる可能性があります。

次のコード スニペットでは:

<code class="go">func TestGetUID(t *testing.T) {
    namespace := "lkfm"
    expecteduid := "fake_uid"
    var tests = []struct {
        description string
        expected    string
        namespace   string
        objs        []runtime.Object
    }{
        {"PositiveScenario", expecteduid, namespace, []runtime.Object{simpleNamespace(namespace)}},
    }

    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>

lint チェッカーにより、「範囲スコープでの変数の使用」というエラーが発生します。 x 関数リテラル (scopelint)".

問題の理解

このエラーは、t.Run() に渡される関数リテラル内でループ変数 x を使用することに起因します。コンパイラは、 t.Run() が戻った後に関数リテラルが呼び出されるかどうかを知りません。存在する場合、関数リテラルはループ変数を参照することになり、次の反復の値で上書きされる可能性があります。

解決策: 変数コピーの使用

この問題を解決するには、次のように変更します。ループ変数の値を関数リテラルに渡すか、そのコピーを作成するコード。関数のシグネチャは固定されているため、次のように変数のコピーを作成します。

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

次に、関数リテラル内で x2 を参照します。これにより、lint チェッカーは満足します。

あるいは、コピーを作成する意図が明確であるため、コピーとループ変数の両方に同じ名前を使用できます。

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

Thisループ変数をシャドウし、関数リテラルに対してローカルにします。

以上がGo で「関数リテラル (scopelint) で範囲スコープ x の変数を使用する」問題に対処する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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