Hi,
with the new MakeFunc, it is possible to make generic functions
and "attach" them to a struct, e.g.
type S struct { F func(int,int) (int, int) }
func Assign(ptr interface{}, field string, generic func(in []reflect.Value) []reflect.Value){
fv := reflect.ValueOf(ptr).Elem()
p := fv.FieldByName(field)
v := reflect.MakeFunc(p.Type(), generic)
p.Set(v)
}
func Swap(in []reflect.Value) []reflect.Value { return []reflect.Value{in[1],in[0]} }
func main() {
s := &S{}
Assign(s, "F", Swap)
fmt.Println(s.F(2,1))
}
From the outside it looks as if s.F() was a method call.
However, it does not fullfill an interface, e.g.
type I interface {
F(int, int) (int, int)
}
func main() {
s := &S{}
Assign(s, "F", Swap)
fmt.Println(s.F(2,1))
var i I
i = s
}
results in:
S.F is a field, not a method
cannot use s (type *S) as type I in assignment:
*S does not implement I (missing F method)
Now the question to the language implementors:
--------------------------------------------------------------------
Would it require a major effort to allow fields of structs that are functions to
fullfill an interface that requires a method with the same name and signature?
------------------------------------------------------------------------------------------------------
That would be a very powerful combination. Even the struct itself could be passed
in via closure, e.g.
func AddX(i interface{}) func (in []reflect.Value) []reflect.Value {
return func (in []reflect.Value) []reflect.Value {
v := in[0].Int() + reflect.ValueOf(i).Elem().FieldByName("X").Int()
return []reflect.Value{reflect.ValueOf(v)}
}
}
type S1 struct {
Add func(int) (int64)
X int
}
func main() {
s := &S1{X: 2}
Assign(s, "Add", AddX(s))
fmt.Println(s.Add(3))
}
Regards