4

私は小さな問題に遭遇しましたが、それには少し醜い解決策しかありません。私が最初だとは想像できませんが、SOに関する手がかりは見つかりませんでした。

walk次の (意図的に簡略化された) 例では、 my である関数にレシーバーが必要filepath.WalkFuncです。

package main

import (
    "fmt"
    "os"
    "path/filepath"
)

type myType bool

func main() {
    var t myType = true

    // would have loved to do something as:
    // _ = filepath.Walk(".", t.walk) 

    // that does not work, use a closure instead    
    handler := func(path string, info os.FileInfo, err error) error {return t.walk(path, info, err)}
    _ = filepath.Walk(".", handler)
}

func (t myType) walk(path string, info os.FileInfo, err error) error {

    // do some heavy stuff on t and paths
    fmt.Println(t, path)

    return err
}

Funcmain()がトリガーされ、 へwalk()のレシーバーがあるため、この醜いクロージャーを への引数として使用する以外に方法が見つかりません。もっと似 たようなものを望んでいましたが、うまくいきません。コンパイルエラー「メソッドt.walkは式ではありません。呼び出す必要があります」が表示されますtwalk()handlerfilepath.Walk()fileWalk(".", t.walk)

この点で私の閉鎖ソリューションは正しいアプローチですか、それとも私が知らないより良いオプションがありますか?

PS。これは、このクロージャー構造を使用して、レシーバーを持つハンドラー関数を渡す必要がある場合の 1 つです。したがって、この質問は、動作よりもハンドラー関数の受け渡しに関連していfilepathます。

ご提案いただきありがとうございます。

4

2 に答える 2

4

これは不可能です。

Go では、メソッドはほとんどがシンタックス シュガーであり、レシーバーは実際には関数の最初のパラメーターです。myType.walk には基本的に署名がありますfunc(myType, string, os.FileInfo, error) error。これは、t.walk の代わりに myType.walk を filepath.Walk に渡そうとするとわかります。

于 2012-10-26T12:46:21.563 に答える
1

質問の filepath の動作を無視すると述べていますが、示されている例はそれに大きく依存しています。

まず、メソッドの受け渡しに対処するために、代わりにインターフェイスを定義してみてください。

パッケージメイン

import (
    "fmt"
)

type Foo interface {
    Bar(a string)
}

type myFoo bool

func (b myFoo) Bar(a string) {
    fmt.Println(b, a)
}

func exec(f Foo) {
    f.Bar("hello from exec")
}

func main() {
    var test myFoo
    exec(test)
}

したがって、上記では、 に渡そうとする代わりに、test.Bar実際execにどの機能を説明するインターフェースを定義してからtest完全に渡すことになります。

filepath.Walk の場合、インターフェイスを定義せず、代わりに関数型を引数として期待します。この場合、メソッドを func 型でラップする必要がありますfilepath.WalkFunc

これを頻繁に行う必要がある場合は、タイプに追加のメソッドを追加できます (テストされていません)。

func (t myType) handlerFunc() filepath.WalkFunc {
    return func(path string, info os.FileInfo, err error) error {
        return t.walk(path, info, err)
    }
}

それから電話するfilepath.Walk(".", t.handlerFunc())

于 2012-10-26T14:08:46.717 に答える