在我的 Golang 代码中,我使用来自 go-redis 的接口函数签名 ZRemRangeByScore,它定义了参数名称“min”和“max”。使用新版本的 revive linter,使用具有相同参数名称的接口现在会导致 lint 错误,例如“redefines-builtin-id:重新定义内置函数 min (revive)”。此 lint 错误的其他变体仅在错误消息中的函数名称不同。
我询问了 ChatGPT,并进行了搜索引擎查询,试图找到告诉 revive 忽略此错误的 //nolint 注释。我从 ChatGPT 或搜索引擎查询得到的唯一答案似乎是错误的,即使用评论
“//nolint:重新定义内置ID”
我认为这是错误的,因为 a) 它会导致一条警告消息“在 //nolint 指令中找到未知的 linters redefines-builtin-id”,并且 b) 在添加此 //nolint 指令之前导致 lint 错误的代码仍然会导致相同的 lint错误。
当我告诉 ChatGPT 这个 //nolint 指令是错误的时,得到的回应是道歉并使用参数文件进行恢复。不幸的是,我正在使用的构建系统使得更改此参数文件变得困难或不可能,因为 revive 是由我不拥有的代码代表我调用的。
我不想通过使用与 go-redis 函数签名中的参数名称不同的参数名称来破坏接口,而是想知道是否存在涉及不同 //nolint 指令的简单修复。或者,如果有必要破坏界面,那么在我这样做之前知道这是唯一的补救措施会很高兴。
除非我遗漏了一些东西(一些代码会很有帮助!),否则我不明白为什么你认为你必须破坏界面。
接口中函数参数的重要属性是这些参数的位置和类型,而不是名称。
如果没有看到您的代码,就无法确定。不过,我认为您应该能够在接口实现中为这些参数使用不同但适当的名称,以避免重新定义
min
/max
并保持 linter 满意。
例如
type Fooable interface {
Foo(len int, max string) // note these names will upset the linter if used in an implementation
}
type fooable struct {}
// Foo implements Fooable. Note the parameter names differ from those in
// the interface declaration, but the position and types match, so the
// interface is satisfied
func (f fooable) Foo(x int, y string) {
// ...
}
事实上,要强调的是,参数的名称与接口契约无关,它们实际上是完全可选的。例如这是上述假设的
Fooable
接口的同样有效的声明:
type Fooable interface {
Foo(int, string)
}
但是,如果命名了任何_参数,则必须为每个方法命名ALL。
即,您可以在接口中使用未命名参数声明一个方法,而使用命名参数声明另一个方法。但是你不能有任何方法只指定一些参数但不是全部参数。
总的来说,我认为命名参数是个好主意。 当然,例外情况是参数的目的和意图足够清楚而没有名称。