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.

Reply via email to