Reputation: 121
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)
})
}
}
Lint give me some problem on :
and it reports this error : "Using the variable on range scope x
in function literal (scopelint)"
Upvotes: 5
Views: 4224
Reputation: 417777
x
is the loop variable which is reused in each iteration. And you create a function literal which you pass to t.Run()
. The compiler does not know (does not have guarantee) whether the created and passed function literal is not called after t.Run()
returns, in which case the function literal would refer to the loop variable which will be overwritten with the value of the next iteration. This is rarely–if ever–the intention. It's often the source of nasty bugs, even data race if the function literal is executed concurrently in another gorotuine.
So go vet
warns about such uses.
Often the solution is to pass the value of the loop variable to the function literal as an argument, or create a copy of the loop variable and refer to the copy. Since the signature of your function literal is fixed (you can't change it), create a copy of the variable, e.g.:
x2 := x
And refer to x2
inside the function literal. This will make go vet
happy.
Also, since the intention of making a copy is clear, you may use the same name, e.g. x := x
, which copy will shadow the loop variable. After the above short variable declaration, the identifier x
will refer to the local copy (and not the loop variable). In general this may cause confusion, but here the intention is clear and acceptable.
Upvotes: 14