8

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?

2 Answers 2

13

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)
}
Sign up to request clarification or add additional context in comments.

Comments

5

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.