【发布时间】:2012-07-04 22:34:27
【问题描述】:
filepath.Walk 函数接受函数回调。这是没有上下文指针的直接函数。当然,Walk 的一个主要用例是遍历一个目录并基于它采取一些行动,并参考更广泛的上下文(例如,将每个文件输入到一个表中)。
如果我在 C# 中编写此代码,我将使用一个对象(具有可以指向上下文中对象的字段)作为回调(具有给定的回调方法),以便对象可以封装 @ 987654325@ 被调用。
(编辑:用户“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 方法的使用目的是如何让回调引用更广泛的上下文?
【问题讨论】:
-
如果你想得到关于 Go 成语这样的问题的几乎即时回复,你应该将它发布到开发团队和贡献者非常活跃的 golang 组:groups.google.com/group/golang-nuts。他们是一个很棒的支持。
-
不是即时的。我有一个解决方案。这更像是一种“最佳实践”。我可能会在 google 群组上发帖,但有消息告诉我我需要一个 google 帐户...
-
您确实需要一个谷歌帐户。但你也会很快得到回复。这是一个非常活跃的群体。