There deferred function here has not any return value - to get discarded. It rather assigns a value to the *closure* *err* variable.
Since a defer statement "*invokes a function whose execution is deferred to the moment the surrounding function returns*", so I expected the *err* variable should have a value just before the return statement executes. The *err* variable is just a closure. Still I'm confused why the first version does not behave as expected - because the actual function *is not invoked yet* at the position of defer statement but just it's parameters. "*Instead, deferred functions are invoked immediately before the surrounding function returns*". Why this is not behaving as expected? On Friday, August 26, 2016 at 3:25:11 AM UTC+4:30, Vasko Zdravevski wrote: > > I put your code snippet in the playground for easier sharing: > https://play.golang.org/p/ZvuNwjS7ZF > > I think the spec has the answer you're looking for regarding how named > result parameters are handled during a panic. > https://golang.org/ref/spec#Defer_statements > > Specifically the sentence: > >> If the deferred function has any return values, they are discarded when >> the function completes. (See also the section on handling panics >> <https://golang.org/ref/spec#Handling_panics>.) >> > > Also, > >> If the function's signature <https://golang.org/ref/spec#Function_types> >> declares >> result parameters, the function body's statement list must end in a >> terminating >> statement <https://golang.org/ref/spec#Terminating_statements>. >> > https://golang.org/ref/spec#Function_declarations > > And the panic is the 'terminating statement' > > Hope this helps, > Vasko. > > On Thursday, August 25, 2016 at 4:19:17 PM UTC-6, dc0d wrote: >> >> Assuming we have this test: >> >> func TestRecover(t *testing.T) { >> f := func() (interface{}, error) { >> panic(`TEST`) >> } >> r, e := Recover(f) >> t.Log(r, e) >> } >> >> And two versions of *Recover* function. >> >> Version 1: >> func Recover(f func() (interface{}, error)) (interface{}, error) { >> var result interface{} >> var err error >> >> defer func() { >> if e := recover(); e != nil { >> err = errors.Error(fmt.Sprintf("%v", e)) >> } >> }() >> >> result, err = f() >> >> return result, err >> } >> >> >> Version 2: >> func Recover(f func() (interface{}, error)) (res interface{}, err error) >> { >> defer func() { >> if e := recover(); e != nil { >> err = errors.Error(fmt.Sprintf("%v", e)) >> } >> }() >> >> res, err = f() >> >> return res, err >> } >> >> >> *Question:* Why the output of test for Version 1 is *<nil> <nil>* (*not >> expected/wrong*) but for Version 2 is *<nil> TEST* (*as expected/correct* >> )? >> >> - Go 1.7, Ubuntu 14.04 x64 >> > -- 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.