传递一个与defer一起使用的方法作为参数

问题描述 投票:3回答:1

我们可以轻松地将函数作为参数传递,并将其与defer一起使用:

func main() {
    test(rec)
}

func test(f func(int)) {
    defer f(10)
    panic("test")
}

func rec(v int) {
    e := recover()
    fmt.Println(e)
    fmt.Println(v)
}

这有效。 Playground


但是如果我们需要传递一个方法然后在该方法中调用recover呢?

type MyStruct struct {
    Data string
}

func main() {
    a := &MyStruct{}
    test(a.Recover)
}

func test(f func(int)) {
    defer f(10)
    panic("test")
}

func (m *MyStruct) Recover(arg int) {
    e := recover()
    fmt.Println(e)
    fmt.Println(arg)
}

在这里我们得到一些奇怪的行为,我不完全理解。 Playground

看起来这个方法被调用但recover返回nil,之后又出现了(另一个?)恐慌。 Golang文档和谷歌搜索结果都没有帮助我理解这种行为的原因。我错过了什么?

go error-handling
1个回答
3
投票

recover()功能returns nil when not called directly from the deferred function

通过method value a.Recover的电话不是直接电话。

使用调用recover和方法的包装函数:

func main() {
    a := &MyStruct{}
    test(func(arg int) { a.Recover(arg, recover()) })
}

func test(f func(int)) {
    defer f(10)
    panic("test")
}

func (m *MyStruct) Recover(arg int, e interface{}) {
    fmt.Println(e)
    fmt.Println(arg)
}

另一个选择是使用method expression,但这可能与你想要完成的事情有所不同:

func main() {
    a := &MyStruct{}
    test(a, (*MyStruct).Recover)
}

func test(a *MyStruct, f func(*MyStruct, int)) {
    defer f(a, 10)
    panic("test")
}

func (m *MyStruct) Recover(arg int) {
    e := recover()
    fmt.Println(e)
    fmt.Println(arg)
}
© www.soinside.com 2019 - 2024. All rights reserved.