如何在Go中获取一个类型化函数的函数指针?

huangapple go评论76阅读模式
英文:

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

问题

以下是翻译好的部分:

以下代码获取了指向函数hello的指针并打印出来:

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)
}

然而,如果我取消底部的注释,编译会报错,显示:

> ./junk.go:14: undefined: hello2

所以我尝试了:

i := &x{}
f2 := &i.hello2
fmt.Printf("%+v\n", f2)

...但是会报错:

> ./junk.go:15: method i.hello2 is not an expression, must be called

好吧,也许我必须直接引用原始类型:

f2 := x.hello2
fmt.Printf("%+v\n", f2)

不行:

> ./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)

这样有点行:

i := &x{}
f2 := reflect.TypeOf(i).Method(0)
fmt.Printf("%+v\n", f2)

然而,得到的f2是一个reflect.Method,而不是一个函数指针。:(

这里应该使用什么适当的语法?

英文:

The following code gets a pointer to the function hello and prints it:

<!-- language: lang-golang -->

package main

import &quot;fmt&quot;

type x struct {}
func (self *x) hello2(a int) {}

func hello(a int) {}

func main() {
    f1 := hello
    fmt.Printf(&quot;%+v\n&quot;, f1)
    
    // f2 := hello2
    // fmt.Printf(&quot;%+v\n&quot;, f2)
}

However, if I un-comment the section at the bottom, the compile errors, saying:

<!-- language: lang-none -->

&gt; ./junk.go:14: undefined: hello2

So I tried:

<!-- language: lang-golang -->

  i := &amp;x{}
  f2 := &amp;i.hello2
  fmt.Printf(&quot;%+v\n&quot;, f2)

...but that errors with:

<!-- language: lang-none -->

&gt; ./junk.go:15: method i.hello2 is not an expression, must be called

Ok, so maybe I have to directly refer to original type:

<!-- language: lang-golang -->

  f2 := x.hello2
  fmt.Printf(&quot;%+v\n&quot;, f2)

Nope:

<!-- language: lang-none -->

&gt; ./junk.go:14: invalid method expression x.hello2 (needs pointer receiver: (*x).hello2)
&gt; ./junk.go:14: x.hello2 undefined (type x has no method hello2)

This sort of works:

<!-- language: lang-golang -->

  i := &amp;x{}
  f2 := reflect.TypeOf(i).Method(0)
  fmt.Printf(&quot;%+v\n&quot;, f2)

However, the resulting f2 is a reflect.Method, not a function pointer. 如何在Go中获取一个类型化函数的函数指针?

What is the appropriate syntax here?

答案1

得分: 13

你可以使用方法表达式,它将返回一个以接收者作为第一个参数的函数。

<!-- language: lang-golang -->

f2 := (*x).hello2
fmt.Printf(&quot;%+v\n&quot;, f2)

f2(&amp;x{}, 123)

否则,你可以将函数调用包装在一个接受x作为参数的函数中。

<!-- language: lang-golang -->

f2 := func(val *x) {
    val.hello2(123)
}

或者闭包一个现有的x值。

<!-- language: lang-golang -->

val := &amp;x{}

f2 := func() {
    val.hello2(123)
}
英文:

You can use method expressions, which will return a function that takes the receiver as the first argument.

<!-- language: lang-golang -->

f2 := (*x).hello2
fmt.Printf(&quot;%+v\n&quot;, f2)

f2(&amp;x{}, 123)

Otherwise you can just wrap the function call in a function that accepts the x as an argument.

<!-- language: lang-golang -->

f2 := func(val *x) {
    val.hello2(123)
}

Or that closes over an existing x value.

<!-- language: lang-golang -->

val := &amp;x{}

f2 := func() {
    val.hello2(123)
}

答案2

得分: 5

Go函数调用和闭包的相关阅读材料:Russ Cox的《Go 1.1 Function Calls》(也详细介绍了Go1)。

https://docs.google.com/document/d/1bMwCey-gmqZVTpRax-ESeVuZGmjwbocYs1iHplK-cjo/pub

英文:

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

huangapple
  • 本文由 发表于 2013年3月12日 10:09:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/15352089.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定