我已经声明了一个新类型func,它采用任何符合interface{}. 但是,当我调用作为参数传递的函数(符合该类型规范)时,我收到错误消息。
有人可以解释为什么会这样吗?下面是我可以重新创建问题的最简单示例。
type myfunc func(x interface{})
func a(num int) {
return
}
func b(f myfunc) {
f(2)
return
}
func main() {
b(a) // error: cannot use a (type func(int)) as type myfunc in argument to b
return
}
Run Code Online (Sandbox Code Playgroud)
您在这里寻找的概念是类型系统中的差异。一些类型系统和类型支持covariance和contravariance,但 Go 的接口不支持。
虽然 anint可以传递给一个期望的函数interface{},但不能说func(int)和func(interface{}),因为接口的行为不是协变的。
如果 typex实现了 interface ii,并不意味着func(x)实现了func(ii).
你可以做的是传递func(int)给一个期望的函数interface{},所以你可以做
package main
import "fmt"
func foo(x interface{}) {
fmt.Println("foo", x)
}
func add2(n int) int {
return n + 2
}
func main() {
foo(add2)
}
Run Code Online (Sandbox Code Playgroud)
因为func(int)int 确实实现了interface{}.
除了答案顶部的 Wikipedia 链接外,这篇文章还提供了有关不同种类的方差编程语言支持的更多详细信息。它主要使用其他语言,因为使用支持继承的语言可以最好地证明差异。