Golang 延迟关闭
Golang Defer a closure
我刚开始学习延迟。我想知道为什么第一个有效而第二个无效。我想知道他们之间有什么区别。
第一:
func say(s string) {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in cleanup:", r)
}
wg.Done()
}()
for i := 0; i < 3; i++ {
fmt.Println(s)
time.Sleep(time.Millisecond * 100)
if i == 2 {
panic("oh")
}
}
}
第二个:
func cleanup(){
if r := recover(); r != nil {
fmt.Println("Recovered in cleanup:", r)
}
}
func say(s string) {
defer func() {
cleanup()
wg.Done()
}()
for i := 0; i < 3; i++ {
fmt.Println(s)
time.Sleep(time.Millisecond * 100)
if i == 2 {
panic("oh")
}
}
}
The return value of recover is nil if any of the following conditions holds:
...
- recover was not called directly by a deferred function.
cleanup()
函数被匿名延迟函数调用。重写代码直接延迟cleanup()
。
func say(s string) {
defer wg.Done()
defer cleanup() // cleanup called directly by defer
for i := 0; i < 3; i++ {
fmt.Println(s)
time.Sleep(time.Millisecond * 100)
if i == 2 {
panic("oh")
}
}
}
从 https://golang.org/pkg/builtin/#recover 开始,我们有以下内容(强调我的):
The recover built-in function allows a program to manage behavior of a panicking goroutine. Executing a call to recover inside a deferred function (but not any function called by it) stops the panicking sequence by restoring normal execution and retrieves the error value passed to the call of panic. If recover is called outside the deferred function it will not stop a panicking sequence. In this case, or when the goroutine is not panicking, or if the argument supplied to panic was nil, recover returns nil. Thus the return value from recover reports whether the goroutine is panicking.
按照规格https://golang.org/ref/spec#Handling_panics
如果满足以下任一条件,recover 的 return 值为 nil:
- panic 的参数为零
- goroutine 没有 panic
- 恢复不是由延迟函数直接调用的。
在你的情况下,recover 不是由延迟函数直接调用的。
我刚开始学习延迟。我想知道为什么第一个有效而第二个无效。我想知道他们之间有什么区别。 第一:
func say(s string) {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in cleanup:", r)
}
wg.Done()
}()
for i := 0; i < 3; i++ {
fmt.Println(s)
time.Sleep(time.Millisecond * 100)
if i == 2 {
panic("oh")
}
}
}
第二个:
func cleanup(){
if r := recover(); r != nil {
fmt.Println("Recovered in cleanup:", r)
}
}
func say(s string) {
defer func() {
cleanup()
wg.Done()
}()
for i := 0; i < 3; i++ {
fmt.Println(s)
time.Sleep(time.Millisecond * 100)
if i == 2 {
panic("oh")
}
}
}
The return value of recover is nil if any of the following conditions holds:
...
- recover was not called directly by a deferred function.
cleanup()
函数被匿名延迟函数调用。重写代码直接延迟cleanup()
。
func say(s string) {
defer wg.Done()
defer cleanup() // cleanup called directly by defer
for i := 0; i < 3; i++ {
fmt.Println(s)
time.Sleep(time.Millisecond * 100)
if i == 2 {
panic("oh")
}
}
}
从 https://golang.org/pkg/builtin/#recover 开始,我们有以下内容(强调我的):
The recover built-in function allows a program to manage behavior of a panicking goroutine. Executing a call to recover inside a deferred function (but not any function called by it) stops the panicking sequence by restoring normal execution and retrieves the error value passed to the call of panic. If recover is called outside the deferred function it will not stop a panicking sequence. In this case, or when the goroutine is not panicking, or if the argument supplied to panic was nil, recover returns nil. Thus the return value from recover reports whether the goroutine is panicking.
按照规格https://golang.org/ref/spec#Handling_panics
如果满足以下任一条件,recover 的 return 值为 nil:
- panic 的参数为零
- goroutine 没有 panic
- 恢复不是由延迟函数直接调用的。
在你的情况下,recover 不是由延迟函数直接调用的。