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.

Reply via email to