关闭 – 我如何使用Filepath.Walk在Go?

filepath.Walk函数需要一个函数回调函数。这是没有上下文指针的直接函数。当然,Walk的一个主要用例是参考一个更广泛的上下文(例如,将每个文件输入表格)中的目录,并采取一些行动。

如果我在C#中写这个,我将使用一个对象(可以指向上下文中的对象的对象)作为一个回调(带有一个给定的回调方法),所以对象可以封装Walk所调用的上下文。

(编辑:用户“usr”表示闭包方法也发生在C#中)

如果我在C中写这个,我会要求一个函数和一个上下文指针作为一个void *,所以该函数有一个上下文指针,它可以传递到Walk函数,并将它传递给回调函数。

但是Go只有函数参数,没有明显的上下文指针参数。

(如果我设计了这个函数,我将把一个对象作为一个回调而不是一个函数,符合接口FileWalkerCallback或者其他的东西,并在该接口上放置一个回调(…)方法,然后消费者可以附加任何上传到对象,然后传递给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方法以这样的方式使回调有更广泛的上下文的引用?

你在做正确的事情。你可能会考虑两个小小的变化。一个是可以用一个下划线替换未使用参数的名称。所以,在你只使用路径的例子中,签名可以读取

func(path string, _ os.FileInfo, _ error) error

它节省了一些打字,清理代码,并清楚地表明您没有使用参数。另外,对于小函数,特别是通常的是将函数文字分配给一个变量,并直接用作参数。你的代码结束了阅读,

err = filepath.Walk(location, func(path string, _ os.FileInfo, _ error) error {
    numScanned ++

    myStorageThing.DoSomething(path)
})

这清理了一些范围,清楚地表明你只是一次使用关闭。

http://stackoverflow.com/questions/11336048/how-am-i-meant-to-use-filepath-walk-in-go

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:关闭 – 我如何使用Filepath.Walk在Go?