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)
}
We can call it by
Println(3)
Println(1.5)
Println("Hello")
But I can't achieve the same thing for function type
func Map(fn func( interface{} )) {
......
}
I cannot call this with
Map( func( i int) {......} )
because the type func(int)
is different from the type func( interface{} )
.
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.
When you call
Println(3)
, the function isn't taking an integer as its first argument. Rather the integer gets packed inside aninterface{}
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 matchingfunc(i int)
.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 thereflect
package. Thereflect
package can also help you call arbitrary functions where you don't know the signature at compile time.For example:
This will call the given function
f
with the argumentv
and return the result. Providedv
is assignable tof
's first argument the call will succeed without a panic. You can experiment with this example here: http://play.golang.org/p/kkBu56JYb8I do realise its an old discussion, but came across the post and wanted to play around with the concept of having arbitrary function
func (interface{})
within another function, instead ofinterface{}
. I could write a simple implementation, by providing an inline implementation of a function which would acceptinterface{}
. And we can call this function from within another functionGoing by this, we can write any implementations of
func(interface{})
and pass it as parameter toTakeGenericFunc
You can play around with it here:
https://play.golang.org/p/f5UUhyhEx7u