go - 将要与 defer 一起使用的方法作为参数传递

标签 go error-handling

我们可以轻松地将一个函数作为参数传递并与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,之后出现了(另一个?) panic 。 golang 文档和谷歌结果都没有帮助我理解这种行为的原因。我错过了什么?

最佳答案

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)
}

关于go - 将要与 defer 一起使用的方法作为参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48000276/

相关文章:

magento - 结帐最后一步的firefox卡验证

swift - Swift 3 中的错误处理

php - 无法处理 PHP 的 SoapServer->handle() 方法中的错误

c# - 10秒后出现未处理的异常错误,为什么?

go - 如何在 Golang 中将 int16 转换为十六进制编码的字符串

unit-testing - `go test` CLI 测试报告者的推荐

google-app-engine - Golang GAE 将图像 Url 保存到 Blobstore

ios - 初始化前使用的常量 'error'

go - 解析时间 """"as ""2006-01-02T15 :04:05Z07:0 0"": cannot parse """as "2006"

go - 从 html 标签中清除字符串的最佳方法是什么