Функция 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
таким образом, чтобы обратный вызов имел ссылку на более широкий контекст?