Reputation: 41
Consider the following function -- a binder of the second argument.
func bindSecond(value interface{}, f func(a interface{}, b interface{})) func (c interface{}) {
return func(arg interface{}) {
f(arg, value)
}
}
Consider a function
func f(x int, y int) {}
When trying to use it as a parameter in binder, go compiler says:
cannot use f (type func(int, int)) as type func(interface {}, interface {}) in argument to bindSecond.
Could you please suggest me the proper way of implementing binders in go (golang)?
Upvotes: 1
Views: 454
Reputation: 13072
I see what you're trying to do, some templates, right? But this is not going to work this way. Your f func(a interface{}, b interface{})
argument is not an interface, so it must be of the matching type. You could achieve what you want by passing f interface{}
and then manipulate it with reflect
package.
Some naive example:
package main
import (
"fmt"
"reflect"
)
func bindSecond(value interface{}, f interface{}) func(c interface{}) {
return func(arg interface{}) {
reflect.ValueOf(f).Call([]reflect.Value{reflect.ValueOf(arg), reflect.ValueOf(value)})
}
}
func main() {
sum := func(x int, y int) { fmt.Println(x + y) }
inc := bindSecond(1, sum)
inc(10)
}
// Prints 11
Doable, but not very pretty. And panics in runtime if anything unexpected happens, for example f
is not callable and doesn't take exactly two arguments. Or you pass a wrong type to inc
. Complier won't help you anymore.
Upvotes: 4
Reputation: 3165
Replace interface{}
with int
and it will work.
Or, more to the point, try to find a solution to your original problem using the features Go provides, instead of trying to force a solution from a different paradigm.
Upvotes: 4