関数はfilepath.Walk
関数コールバックを受け取ります。これは、コンテキスト ポインターのない単純な関数です。確かに、 の主な使用例Walk
は、ディレクトリをたどって、より広いコンテキスト (各ファイルをテーブルに入力するなど) を参照して、それに基づいて何らかのアクションを実行することです。
これを C# で記述している場合、オブジェクト (コンテキスト内のオブジェクトを指すことができるフィールドを含む) をコールバック (特定のコールバック メソッドを使用) として使用し、オブジェクトがWalk
呼び出し元のコンテキストをカプセル化できるようにします。
(編集:ユーザー「usr」は、C#でもクロージャメソッドが発生することを示唆しています)
これを C で記述している場合、関数とコンテキスト ポインターを として要求します。そのため、関数には、関数に渡してコールバック関数に渡さvoid *
れたコンテキスト ポインターを取得できます。Walk
しかし、Go には関数引数しかなく、明らかなコンテキスト ポインター引数はありません。
(私がこの関数を設計していたら、オブジェクトを関数ではなくコールバックとして取り、インターフェイスなどに準拠し、そのインターフェイスにメソッドFileWalkerCallback
を配置したでしょうcallback(...)
。消費者は、オブジェクトを渡す前に、オブジェクトに任意のコンテキストをアタッチできます。へWalk
。)
私が考えることができる唯一の方法は、コールバック関数で外部関数のクロージャをキャプチャすることです。これが私がそれを使用している方法です:
func ScanAllFiles(location string, myStorageThing *StorageThing) (err error) {
numScanned = 0
// Wrap this up in this function's closure to capture the `corpus` binding.
var scan = func(path string, fileInfo os.FileInfo, inpErr error) (err error) {
numScanned ++
myStorageThing.DoSomething(path)
}
fmt.Println("Scan All")
err = filepath.Walk(location, scan)
fmt.Println("Total scanned", numScanned)
return
}
この例では、コールバック関数を作成して、そのクロージャーに変数numScanned
とmyStorageThing
.
これは私には間違っているように感じます。奇妙に感じると思うのは正しいですか、それとも Go を書くことに慣れてきたのでしょうか? filepath.Walk
コールバックがより広いコンテキストへの参照を持つような方法でメソッドを使用することは、どのように意図されていますか?