我们可以轻松地将函数作为参数传递,并将其与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文档和谷歌搜索结果都没有帮助我理解这种行为的原因。我错过了什么?
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)
}