[英]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
你可以在这里玩它:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.