I am new to go and learning defer. I am wondering why the first one works while the second one not. I wonder what's the difference between them. First:
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")
}
}
}
Second:
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 specification says:
The return value of recover is nil if any of the following conditions holds:
...
- recover was not called directly by a deferred function.
The cleanup()
function is called by the anonymous deferred function. Rewrite the code to defer cleanup()
directly.
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")
}
}
}
As per specification https://golang.org/ref/spec#Handling_panics
The return value of recover is nil if any of the following conditions holds:
In your case recover was not directly called by deferred fuction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With