处理程序函数中的接收器,例如filepath.WalkFunc

时间:2012-10-26 12:28:57

标签: go

我遇到了一个小问题,我只有一个丑陋的解决方案。 我无法想象我是第一个,但我没有找到任何关于SO的线索。

在下面(故意简化)的例子中,我希望有一个 walk函数上的接收者是我的filepath.WalkFunc

package main

import (
    "fmt"
    "os"
    "path/filepath"
)

type myType bool

func main() {
    var t myType = true

    // would have loved to do something as:
    // _ = filepath.Walk(".", t.walk) 

    // that does not work, use a closure instead    
    handler := func(path string, info os.FileInfo, err error) error {return t.walk(path, info, err)}
    _ = filepath.Walk(".", handler)
}

func (t myType) walk(path string, info os.FileInfo, err error) error {

    // do some heavy stuff on t and paths
    fmt.Println(t, path)

    return err
}

Func main()触发walk(),由于接收器t触发walk(),我 除了使用这个丑陋的闭包handler作为参数之外,找不到另一种方法 到filepath.Walk()。我希望有更多的东西 fileWalk(".", t.walk)但这不起作用。它给出了编译错误 “方法t.walk不是表达式,必须称为”

我的闭包解决方案在这方面是正确的方法,还是有更好的选择我不知道。

PS。这是我必须使用这种闭合结构的几种情况之一 传递具有接收器的处理函数。所以,这个问题更相关 传递处理函数而不是filepath行为。

谢谢你的建议。

2 个答案:

答案 0 :(得分:4)

这是不可能的。

在Go中,方法主要是语法糖,接收器实际上是函数的第一个参数。 myType.walk基本上有签名func(myType, string, os.FileInfo, error) error。当您尝试将myType.walk传递给filepath.Walk而不是t.walk时,可以看到这一点。

答案 1 :(得分:1)

虽然你提到忽略了问题的文件路径行为,但给出的例子很大程度上取决于它。

首先,要解决方法中的传递问题,请尝试定义接口。

package main

import (
    "fmt"
)

type Foo interface {
    Bar(a string)
}

type myFoo bool

func (b myFoo) Bar(a string) {
    fmt.Println(b, a)
}

func exec(f Foo) {
    f.Bar("hello from exec")
}

func main() {
    var test myFoo
    exec(test)
}

因此,在上文中,您实际上定义了一个描述功能的接口,然后完全传入test.Bar,而不是尝试将exec传递给test

对于filepath.Walk,它不定义接口,而是期望函数类型作为参数。在这种情况下,您需要使用func类型filepath.WalkFunc

包装您的方法

如果你发现自己需要做很多事情(未经测试),你可以为你的类型添加一个额外的方法

func (t myType) handlerFunc() filepath.WalkFunc {
    return func(path string, info os.FileInfo, err error) error {
        return t.walk(path, info, err)
    }
}

然后拨打filepath.Walk(".", t.handlerFunc())

相关问题