2 回答
TA贡献1798条经验 获得超3个赞
在查看了我所看到的所有反馈和写作之后,我将在这里总结调查结果。
如果您在看到来自 Goland 之类的工具的 Go linting 警报后正在调查此行为,希望此答案能同时为您节省时间并明确表示它是可以的、惯用的,并且只有在初始化后重用实际包调用的某些情况下才会出现任何问题有经验。
使用局部变量隐藏包名称
这是一个见仁见智的问题,没有官方声明表明这被认为是非惯用代码。
意见似乎总体上倾向于避免阴影,除非为了清晰和可读性而故意这样做,但这又是意见,而不是要求。
一旦被覆盖,该包将在该范围内不可用,因为包名称已被局部变量隐藏。
我观察到这种行为在 Go 中似乎比某些语言更有可能,因为 Go 提示的包名称很短,不是多字,而且易于输入。
assert := assert.New(t)
当这种情况发生时,这似乎是不可避免的。在此类问题上,始终如一的一致性是关键。如果团队决定永远不隐藏包名称,则
assertions := assert.New(t)
可以使用,或者如前所述,包可以使用别名,例如import tassert "github.com/stretchr/testify/assert"
. 这是一个意见标准,无论哪种方式都是合法的并且被认为是惯用的。在测试的情况下,这通常是在不进一步使用初始变量集之后进一步使用包来完成的。下面的示例使用
is
is 包。包作者对此发表评论(同样这是固执己见,但与is := is.New(t)
.
package package_test
import (
"testing"
"package"
iz "github.com/matryer/is"
)
func TestFuncName(t *testing.T) {
is := iz.New(t)
got := FuncName()
want := ""
is.Equal(got,want) // AssertMessage
}
影子行为可以解决 Goroutine 变量问题
Shadowing 是一种已知行为,并在Effective Go中有明确记录。
错误在于,在 Go for 循环中,循环变量在每次迭代中都被重用,因此 req 变量在所有 goroutine 之间共享。这不是我们想要的。
写起来可能看起来很奇怪,
req := req
但在 Go 中这样做是合法且惯用的。你会得到一个新版本的同名变量,故意在本地隐藏循环变量,但每个 goroutine 都是唯一的。
这也可以通过将变量作为参数传递到嵌入式 func 中来解决,从而简化代码。两者都是合法的,并且根据指南被认为是惯用的。
阴影测试
与这种 goroutine 行为相关,但在测试的上下文中,并行测试在 goroutine 中运行,因此也可以从这种模式中受益。
tc := tc 语句在并行测试示例中是必需的,因为闭包在 goroutine 中运行。更一般地说,在闭包的上下文中使用的 tc := tc 习语可以在下一次循环迭代开始后执行闭包 - 注释中的 @gopher
Be Careful With Table Driven Tests的要点在How To Solve This中也提到了这种行为。
检测
该检查go vet
可以检查阴影,但不被视为稳定包的一部分,并在此处与GitHub 问题 29260和GitHub 问题 34053相关的内容被删除。unsafeptr
由于标志的要求,似乎出于兼容性目的提示了更改。其他评论似乎指出在go vet
未经实验的情况下允许进入之前还需要更好的启发式方法。
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow go vet -vettool=$(which shadow)
对于那些想要对此进行检查的人,golangci-lint
确实可以选择在配置中配置阴影检查(搜索check-shadowing
该文本块的无书签`。
TA贡献1853条经验 获得超18个赞
哇,那是糟糕的代码。虽然它可能不是编译器强制执行的规则,但如果我看到:
import "github.com/stretchr/testify/assert"
然后在那个文件中,就我而言,任何拼写的标识符assert
都是从那个包的顶级导入,句号。任何以“聪明”或其他名义打破这种模式的人都是在自找麻烦。人们的肌肉记忆被训练来识别顶级进口,所以请不要做这样的事情。如果您想避免考虑新名称,只需删除一些字母:
asrt := assert.New(t)
或添加一个字母:
nAssert := assert.New(t)
或别名导入:
import tAssert "github.com/stretchr/testify/assert"
请不要遵循该代码中给出的糟糕示例。
- 2 回答
- 0 关注
- 73 浏览
添加回答
举报