On Thursday, October 13, 2016 at 1:30:48 AM UTC+8, Ian Lance Taylor wrote: > > On Wed, Oct 12, 2016 at 9:21 AM, <di...@veryhaha.com <javascript:>> > wrote: > > I don't like the spec docs for panic/recover in Golang, for the spec > docs is > > vague and not clear on when recover will take effect. > > > > So I wrote some examples to get the mechanism of panic/recover in > Golang. > > > > // example A > > func main() { > > defer func() { > > fmt.Println(recover()) > > }() > > panic(1) // recovered > > } > > > > ========= result: > > 1 > > > > > > > > // example B > > func main() { > > defer func() { > > defer func() { > > fmt.Println(recover()) > > }() > > > > panic(2) // recovered > > }() > > panic(1) // not recover > > } > > > > ========= result: > > 2 > > panic: 1 > > > > > > > > // example c > > func main() { > > defer func() { > > defer func() { > > recover() > > panic(3) > > }() > > panic(2) > > }() > > panic(1) > > } > > > > ========= result: > > 2 > > panic: 1 > > panic: 2 [recovered] > > panic: 3 > > > > > > > > > > // example D > > func main() { > > defer func() { > > recover() > > }() > > defer func() { > > panic(2) // recovered, (overwrite 1) > > }() > > defer func() { > > panic(1) // recovered, (overwritten by 2) > > }() > > } > > > > ========= result: > > 2 > > > > > > > > // example E > > func main() { > > defer func() { > > defer func() { > > fmt.Println(recover()) > > }() > > }() > > panic(1) // not recover > > } > > > > ========= result: > > <nil> > > panic: 1 > > > > > > > > // example F > > func main() { > > defer func() { > > func() { > > fmt.Println(recover()) > > }() > > }() > > panic(1) // not recover > > } > > > > ========= result (same as last one): > > <nil> > > panic: 1 > > > > > > > > > > // example G > > func main() { > > defer fmt.Println(recover()) > > panic(1) // not recover > > } > > > > ========= result: > > <nil> > > panic: 1 > > > > > > // example H > > func main() { > > defer func() { > > fmt.Println(recover()) > > }() > > > > func() { > > func() { > > panic(1) // recovered > > }() > > }() > > } > > > > ========= result: > > 1 > > > > > > So, it looks the calling of recover only takes effect only when both of > the > > following two conditions are met: > > 1. the caller of calling recover must be a deferred function calling . > > 2. the panic must happened in (may not originate from) the caller > function > > of caller of calling recover. > > > > Where or not the calling of recover is deferred or not is not important. > > > > Is the conclusion right? > > The rules are in the language spec: > > The return value of recover is nil if any of the following conditions > holds: > > * panic's argument was nil; > * the goroutine is not panicking; > * recover was not called directly by a deferred function. > > If I understand your rule 1 correctly, it is the same as the third > rule in the spec, though they are reversed because you are describing > the case where recover returns non-nil and the spec is describing the > case where recover returns nil. > > I don't understand your rule 2. We agree that recover must be called > from a deferred function, so what is the caller of the caller of > calling recover? > > You may want to review the files test/recover*.go in the Go sources. > > Ian >
Thanks, Ian. The recover1.go has many great examples to understand the mechanism of panic/recover. I think I have get it. And I still think the spec doc is shallow. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.