在函数字面量 (scopelint) 中使用范围作用域 `x` 上的变量 [英] Using the variable on range scope `x` in function literal (scopelint)

查看:31
本文介绍了在函数字面量 (scopelint) 中使用范围作用域 `x` 上的变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 给我一些问题:

Lint give me some problem on :

  • client := fake.NewSimpleClientset(x.objs...)
  • 实际 := getUID(client, x.namespace)
  • assert.Equal(t, x.expected, actual)

并报告此错误:在函数文字 (scopelint) 中使用范围范围 x 上的变量"

and it reports this error : "Using the variable on range scope x in function literal (scopelint)"

推荐答案

x 是在每次迭代中重复使用的循环变量.然后您创建一个函数文字,将其传递给 t.Run().编译器不知道(不能保证)在 t.Run() 返回后是否不调用创建和传递的函数文字,在这种情况下,函数文字将引用循环变量被下一次迭代的值覆盖.这很少——如果有的话——意图.如果函数文字在另一个 gorotuine 中同时执行,它通常是令人讨厌的错误的来源,甚至是数据竞争.

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.

所以 go vet 警告此类用途.

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

并在函数字面量中引用x2.这会让去兽医高兴.

And refer to x2 inside the function literal. This will make go vet happy.

此外,由于制作副本的意图很明确,您可以使用相同的名称,例如x := x,该副本将隐藏循环变量.在上述短变量声明之后,标识符 x 将引用本地副本(而不是循环变量).一般来说,这可能会引起混淆,但这里的意图是明确且可以接受的.

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.

这篇关于在函数字面量 (scopelint) 中使用范围作用域 `x` 上的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆