On Wed, Oct 12, 2016 at 9:21 AM, <[email protected]> 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
--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.