函数类型中的空接口{} [英] Empty interface{} in function type

查看:74
本文介绍了函数类型中的空接口{}的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以将任何类型的对象分配给一个空接口.例如,我们有以下功能

An object of any type can be assigned to an empty interface. For example, we have the following function

func Println(i interface{} ) {
  fmt.Println(i)
}

我们可以通过

Println(3)
Println(1.5)
Println("Hello")

但是对于函数类型,我无法实现相同的目的

But I can't achieve the same thing for function type

func Map(fn func( interface{} )) {  
  ......  
}  

我不能用
来称呼它 Map( func( i int) {......} )
因为类型func(int)与类型func( interface{} )不同.

I cannot call this with
Map( func( i int) {......} )
because the type func(int) is different from the type func( interface{} ).

但是当我定义func( interface{} )时,实际上是指任何类型的输入参数.如何在Go中实现这一目标?

But when I define func( interface{} ), I really mean any type of the input parameters. How can I achieve this in Go?

推荐答案

失败,因为签名不匹配.

It fails because the signatures don't match.

调用Println(3)时,该函数未将整数作为其第一个参数.而是将整数打包在interface{}变量内(自动转换,因为整数符合接口),然后将该变量传递给函数.这种转换发生在调用方,因此调用函数的过程与调用与func(i int)匹配的函数不同.

When you call Println(3), the function isn't taking an integer as its first argument. Rather the integer gets packed inside an interface{} variable (an automatic conversion, since integers conform to the interface), and that variable is passed to the function. This conversion happens on the calling side, so the process of calling the function is different to calling a function matching func(i int).

如果要编写一个接受任意一元函数的函数,则需要声明它以interface{}变量作为其参数,然后使用reflect包检查该值. reflect程序包还可以帮助您在编译时不知道签名的地方调用任意函数.

If you want to write a function that accepts arbitrary unary functions, you will need to declare it to take an interface{} variable as its argument and then check the value using the reflect package. The reflect package can also help you call arbitrary functions where you don't know the signature at compile time.

例如:

func Map(f, v interface{}) interface{} {
    fn := reflect.ValueOf(f)
    fnType := fn.Type()
    if fnType.Kind() != reflect.Func || fnType.NumIn() != 1 || fnType.NumOut() != 1 {
        panic("Expected a unary function returning a single value")
    }
    res := fn.Call([]reflect.Value{reflect.ValueOf(v)})
    return res[0].Interface()
}

这将使用参数v调用给定的函数f并返回结果.如果v可分配给f的第一个参数,则调用将成功而不会出现紧急情况.您可以在此处尝试使用此示例: http://play.golang.org/p/kkBu56JYb8

This will call the given function f with the argument v and return the result. Provided v is assignable to f's first argument the call will succeed without a panic. You can experiment with this example here: http://play.golang.org/p/kkBu56JYb8

这篇关于函数类型中的空接口{}的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆