The following code gets a pointer to the function hello
and prints it:
package main
import "fmt"
type x struct {}
func (self *x) hello2(a int) {}
func hello(a int) {}
func main() {
f1 := hello
fmt.Printf("%+v\n", f1)
// f2 := hello2
// fmt.Printf("%+v\n", f2)
}
However, if I un-comment the section at the bottom, the compile errors, saying:
> ./junk.go:14: undefined: hello2
So I tried:
i := &x{}
f2 := &i.hello2
fmt.Printf("%+v\n", f2)
...but that errors with:
> ./junk.go:15: method i.hello2 is not an expression, must be called
Ok, so maybe I have to directly refer to original type:
f2 := x.hello2
fmt.Printf("%+v\n", f2)
Nope:
> ./junk.go:14: invalid method expression x.hello2 (needs pointer receiver: (*x).hello2)
> ./junk.go:14: x.hello2 undefined (type x has no method hello2)
This sort of works:
i := &x{}
f2 := reflect.TypeOf(i).Method(0)
fmt.Printf("%+v\n", f2)
However, the resulting f2
is a reflect.Method
, not a function pointer. :(
What is the appropriate syntax here?
You can use method expressions, which will return a function that takes the receiver as the first argument.
f2 := (*x).hello2
fmt.Printf("%+v\n", f2)
f2(&x{}, 123)
Otherwise you can just wrap the function call in a function that accepts the x
as an argument.
f2 := func(val *x) {
val.hello2(123)
}
Or that closes over an existing x
value.
val := &x{}
f2 := func() {
val.hello2(123)
}
Relevant reading on Go function calls and closures: "Go 1.1 Function Calls" by Russ Cox (which covers Go1 in details too).
https://docs.google.com/document/d/1bMwCey-gmqZVTpRax-ESeVuZGmjwbocYs1iHplK-cjo/pub
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With