繁体   English   中英

函数类型中的Golang空接口{}

[英]Golang empty interface{} in function type

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

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

我们可以称之为

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

但是我无法为功能类型实现同样的功能

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

我不能称之为
Map( func( i int) {......} )
因为类型func(int)不同于类型func( interface{} )

但是当我定义func( interface{} ) ,我的意思是任何类型的输入参数。 我怎样才能在Golang中实现这一目标?

它失败,因为签名不匹配。

当您调用Println(3) ,该函数不会将整数作为其第一个参数。 相反,整数被打包在一个interface{}变量中(一个自动转换,因为整数符合接口),并且该变量被传递给该函数。 这种转换发生在调用端,因此调用函数的过程与调用匹配func(i int)的函数不同。

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

例如:

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

我确实意识到它是一个古老的讨论,但遇到了这个帖子,并希望在另一个函数中使用任意函数func (interface{})的概念,而不是interface{} 我可以通过提供一个接受interface{}的函数的内联实现来编写一个简单的实现。 我们可以从另一个函数中调用此函数

varForGenFunc := func(in interface{}) int {                             
                    fmt.Println("type of this object: ",reflect.TypeOf(in))
                    return 1}

TakeGenericFunc(varForGenFunc, variableForGen)

通过这种方式,我们可以编写func(interface{})任何实现,并将其作为参数传递给TakeGenericFunc

你可以在这里玩它:

https://play.golang.org/p/f5UUhyhEx7u

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM