7

次のコードは、関数へのポインターを取得して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)

ただし、結果f2reflect.Method関数ポインタではなく、です。:(

ここでの適切な構文は何ですか?

4

2 に答える 2

11

メソッド式を使用できます。この式は、レシーバーを最初の引数として受け取る関数を返します。

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

f2(&x{}, 123)

xそれ以外の場合は、引数としてを受け入れる関数で関数呼び出しをラップすることができます。

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

または、既存のx値を閉じます。

val := &x{}

f2 := func() {
    val.hello2(123)
}
于 2013-03-12T02:15:53.430 に答える
4

Go関数呼び出しとクロージャに関する関連資料:RussCoxによる「Go1.1関数呼び出し」(Go1についても詳しく説明しています)。

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

于 2013-03-12T12:31:50.207 に答える