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 サイトの他の関連記事を参照してください。