我。改变功能
调用它们将继续工作而无需修改,但由于函数签名不匹配,这可能很容易破坏一些代码。
例如(在Go Playground上试试):
func Foo(a int) {}
func Foo2(a int, params ...string) {}
func main() {
var f func(int)
f = Foo
f = Foo2 // Compile-time error!
_ = f
}
f = Foo2 行产生编译时错误:
不能在赋值中使用 Foo2 (type func(int, ...string)) 作为类型 func(int)
所以这是一个向后不兼容的更改,不要这样做。
上面的例子给出了一个编译时错误,这是幸运/更好的情况,但也可能有代码只会在运行时失败(如果/何时发生这种情况是不确定的),就像在这个例子中一样:
func Foo(a int) {}
func Foo2(a int, params ...string) {}
func main() {
process(Foo)
process(Foo2) // This will panic at runtime (type assertion will not hold)!
}
func process(f interface{}) {
f.(func(int))(1)
}
调用process(foo) 成功,调用process(foo2) 会在运行时panic。在Go Playground 上试试吧。
二。改变方法
您的问题是针对函数的,但是方法也存在同样的“问题”(当用作method expressions 或method values 时,例如参见golang - pass method to function)。
此外,这可能会破坏隐式接口实现(它可能使类型不实现接口),就像在这个示例中一样(在Go Playground 上尝试):
type Fooer interface {
Foo(int)
}
type fooImpl int
func (fooImpl) Foo(a int) {}
type fooImpl2 int
func (fooImpl2) Foo(a int, params ...string) {}
func main() {
var f Fooer
f = fooImpl(0)
f = fooImpl2(0) // Compile time error!
_ = f
}
因为签名不匹配,fooImpl2 不实现 Fooer,即使 fooImpl 实现:
cannot use fooImpl2(0) (type fooImpl2) as type Fooer in assignment:
fooImpl2 does not implement Fooer (wrong type for Foo method)
have Foo(int, ...string)
want Foo(int)