As was said above, the defer becomes active when executed, so defer func()
*before* the potential returns.

Also as was said just before that, the power is clear in more complex
situations. Imagine three things that must be set-up in advance and closed
down properly (open/close network link, files, negotiate protocols,
whatever). Let's call the A, B, and C. The the code looks like:

func BeSafe() error {
if a, errA := setUpA(...); errA != nil {
    // a failed
   return errA
}
defer takeDownA(a)

if b, errB := setUpB(a, ...); errB != nil {
    // b failed
   return errB // takeDownA will be called magically before the return
}
defer takeDownB(b)

if c, errV := setUpC(b, ...); errC != nil {
    // c failed
   return errC // takeDownB and then takeDownA will be called magically
before the return
}
defer takeDownC(c)

//main body of function using A, B, and C
:
if (doneEarly) {
    return nil  // takeDownC, then takeDownB, then takeDownA will be called
magically before the return
}
:

return nil  // takeDownC, then takeDownB, then takeDownA will be called
magically before the return
}

The power of this is that:
(a) the "i've got A set up and I know it will e taken down properly"
confidence is established in one place, where A is set up. (and B and C).
(b) the "time to quit my loop and I don't remember anything about A, B, and
C's special needs" bug is impossible.
(c) the "I'm quitting so take down B, A, and C" bug is impossible.

Pretty clever of the Go team:

*Intellectuals solve problems, geniuses prevent them. *
    —Albert Einstein


Michael


On Fri, Jan 4, 2019 at 1:56 AM <alive.s...@gmail.com> wrote:

>
>
> if err not equal nil ,defer not push stack yet,so it wont execute.
> As below it will execute
>
> func main() {
>
>    src, err := os.Open("text.txt")
>
>    defer src.Close()
>
> if err != nil {
> return
> }
>
> }
>
>
>
>
> On Friday, January 4, 2019 at 2:09:51 PM UTC+8, 伊藤和也 wrote:
>>
>> In the first example, "ok" was not printed.
>>
>> func main() {
>>    if(true) {
>>       return
>>    }
>>    defer fmt.Println("ok")
>> }
>>
>> So in the second example, is the Close function executed after an error 
>> occurs and returned.
>>
>> func main() {
>>    src, err := os.Open("text.txt")
>>    if err != nil {
>>       return
>>    }
>>    defer src.Close()
>> }
>>
>> --
> 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.
>


-- 

*Michael T. jonesmichael.jo...@gmail.com <michael.jo...@gmail.com>*

-- 
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