Go 类型func与接口参数不兼容错误

Go 类型func与接口参数不兼容错误,go,Go,我声明了一个新类型func,它接受符合接口{}的任何值。然而,当我调用一个作为参数传递的函数(符合该类型规范)时,我会得到一个错误 有人能解释一下为什么会这样吗?下面是我可以用的最简单的例子 type myfunc func(x接口{}) func a(num int){ 返回 } func b(f myfunc){ f(2) 返回 } func main(){ b(a)//错误:无法在b的参数中使用a(type func(int))作为类型myfunc 返回 } 您在这里寻找的概念是。某些类型

我声明了一个新类型
func
,它接受符合
接口{}
的任何值。然而,当我调用一个作为参数传递的函数(符合该类型规范)时,我会得到一个错误

有人能解释一下为什么会这样吗?下面是我可以用的最简单的例子

type myfunc func(x接口{})
func a(num int){
返回
}
func b(f myfunc){
f(2)
返回
}
func main(){
b(a)//错误:无法在b的参数中使用a(type func(int))作为类型myfunc
返回
}

您在这里寻找的概念是。某些类型系统和类型支持协方差和逆变,但Go的接口不支持

虽然可以将
int
传递给需要
接口{}
的函数,但对于
func(int)
func(接口{})
则不能这样说,因为接口的行为并不协变

如果type
x
实现接口
ii
,并不意味着
func(x)
实现
func(ii)

您可以将
func(int)
传递到一个需要
接口{}
的函数中,这样您就可以

package main

import "fmt"

func foo(x interface{}) {
    fmt.Println("foo", x)
}

func add2(n int) int {
    return n + 2
}

func main() {
    foo(add2)
}
因为
func(int)int
实现了
接口{}



除了答案顶部的Wikipedia链接外,还提供了有关不同种类的编程语言支持的更多详细信息。它主要使用其他语言,因为支持继承的语言最能体现差异。

a
只能接受整数,
b
需要一个可以接受任何内容的func。如果将
a
传递给
b
,但
b
将“astring”传递给它的
f
参数,在这种情况下,它是
a
,而不是传递
2
,那将是一个错误,对吗?所以编译器阻止你这么做。@mkopriva那么你是说因为
b
理论上可以将任何东西传递给它的参数
f
,编译器会生成一个错误?正如@mkopriva已经解释过的,以下两个不兼容:func(int)和func(interface{})。在您的案例b中,需要第2种类型,但您正在传递第1种类型。编译器生成错误,因为两种类型,
func(int)
func(interface{})
,不相同,也不兼容。该错误的好处是,您无法编写将字符串传递给需要int的函数的程序。首先要了解的是:
interface{}
并不表示“任何类型”。真的没有<代码>接口{}是一种类似uint16的静态类型,表示“空接口”。虽然您可以将所有内容分配给“空接口”类型的变量,但空接口不同于uint16、int或其他任何类型的变量。函数签名必须与每个静态类型上的一个匹配。