Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you get a function pointer to a typed function in go?

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?

like image 878
Doug Avatar asked Mar 12 '13 02:03

Doug


2 Answers

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)
}
like image 188
the system Avatar answered Sep 28 '22 02:09

the system


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

like image 28
mna Avatar answered Sep 28 '22 00:09

mna