具有接口参数不兼容错误的Golang类型的func

问题描述:

I have declared a new type func that takes any value that conforms to interface{}. However, when I invoke a function that has been passed as an argument (conforming to that type specification) I get an error.

Can somebody explain why this is the case? Below is the simplest example I could recreate the issue with.

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
}

我已经声明了一种新类型 func code>,该类型可以采用任何符合的值 接口{} 代码>。 但是,当我调用作为参数传递的函数(符合该类型规范)时,会出现错误。 p>

有人可以解释为什么会这样吗? 以下是我可以使用的最简单示例。 p>

  type myfunc func(x interface {})
 
func a  (num int){
 return 
} 
 
func b(f myfunc){
f(2)
 return 
} 
 
func main(){
b(a)//错误:不能 在b 
 return 
} 
  code>  pre> 
  div>的参数中使用(func(int)类型)作为myfunc类型

The concept you're looking for here is variance in the type system. Some type systems and types support covariance and contravariance, but Go's interfaces do not.

While an int can be passed to a function that expects interface{}, the same cannot be said about func(int) and func(interface{}), because interfaces do not behave covariantly.

If type x implements interface ii, it doesn't mean that func(x) implements func(ii).

What you could do is pass func(int) into a function that expects interface{}, so you could do

package main

import "fmt"

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

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

func main() {
    foo(add2)
}

Because func(int)int does implement interface{}.


In addition to the Wikipedia link at the top of the answer, this post provides more details about the different kinds of variance programming languages support. It mostly uses other languages, because variance is best demonstrated with languages that support inheritance.