Как я должен использовать Filepath.Walk в Go?

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

18
задан Community 23 May 2017 в 11:46
поделиться