Derfer in the middle of Go language

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Defer

There is a good design in the go language, the deferred (defer) statement, where you can add multiple defer statements to a function. When the function executes to the last, these defer statements are executed in reverse order, and finally the function returns. Especially when you are doing some open resources operation, encountered errors need to return early, before returning you need to close the corresponding resources, otherwise it is easy to cause problems such as resource leakage. As shown in the following code, we generally write open a resource that works like this:

Func ReadWrite () bool {    file. Open ("file")//Do some work    if Failurex {        file. Close ()        return False    }    if Failurey {        file. Close ()        return False    }    file. Close ()    return True}

We see a lot of duplicated code on it, and go defer solves this problem effectively. With it, not only is the amount of code reduced a lot, but the program becomes more elegant. The defer function specified later is called before the function exits.

Func ReadWrite () bool {    file. Open ("file")    defer file. Close ()    if Failurex {        return false    }    if Failurey {        return false    }    return True}

If there are many calls, then the last-in- defer defer first-out mode is used, so the following code will output4 3 2 1 0

For I: = 0; I < 5; i++ {    defer FMT. Printf ("%d", I)}


The first impression that defer gave me was that, like in Java,

try {

}finally {

}

My current understanding is that in the function block using defer, is the function corresponding to a stack space, advanced and out. Call the stack at the end of the function to start the defer operation.

If an object is created that consumes memory and needs to be closed in a timely manner, defer cannot be as accurate as try Finnaly.

[Plain]View Plain Copy
  1. Package Main
  2. Import "FMT"
  3. Import "Time"
  4. Type User struct {
  5. Username string
  6. }
  7. Func (this *user) Close () {
  8. Fmt. Println (this.username, "Closed!!!")
  9. }
  10. Func Main () {
  11. U1: = &user{"Jack"}
  12. Defer U1. Close ()
  13. U2: = &user{"Lily"}
  14. Defer U2. Close ()
  15. Time. Sleep (Ten * time. Second)
  16. Fmt. PRINTLN ("Done!")
  17. }
  18. [Vicky@localhost goroutine]$


[Vicky@localhost goroutine]$ Go Run defertest1.go
Done!
Lily Closed!!!
Jack Closed!!!
[Vicky@localhost goroutine]$


In fact, the thread sleep 10 seconds, U1, and U2 can already close (), but need to rely on the end of the main () function in order to defer execution.

Then try adding an internal code area to defer:


[Plain]View Plain Copy
  1. Package Main
  2. Import "FMT"
  3. Import "Time"
  4. Type User struct {
  5. Username string
  6. }
  7. Func (this *user) Close () {
  8. Fmt. Println (this.username, "Closed!!!")
  9. }
  10. Func Main () {
  11. {
  12. Even with the code fast range, the main function body will still have to end before executing defer
  13. U1: = &user{"Jack"}
  14. Defer U1. Close ()
  15. }
  16. U2: = &user{"Lily"}
  17. Defer U2. Close ()
  18. Time. Sleep (Ten * time. Second)
  19. Fmt. PRINTLN ("Done!")
  20. }


Done!
Lily Closed!!!
Jack Closed!!!
[Vicky@localhost goroutine]$


Still defer's execution in done! After. So how do you get to the exact close of try finally?

[Plain]View Plain Copy
  1. Package Main
  2. Import "FMT"
  3. Import "Time"
  4. Type User struct {
  5. Username string
  6. }
  7. Func (this *user) Close () {
  8. Fmt. Println (this.username, "Closed!!!")
  9. }
  10. Func Main () {
  11. U1: = &user{"Jack"}
  12. F (U1)//In such a way that U1 does not rely on the execution of the main function
  13. In this way, U2 does not rely on the execution of the main function
  14. U2: = &user{"Lily"}
  15. M: = Func () {
  16. Defer U2. Close ()
  17. U2 do somthing
  18. // }
  19. M () <pre name= "code" class= "Plain" > func () {
  20. Defer U2. Close ()
  21. U2 do somthing
  22. } () </pre> time. Sleep (Ten * time. Second) fmt. PRINTLN ("Done!")} Func f (U *user) {defer u.close ()//U1 do gomething}


[Vicky@localhost goroutine]$ Go Run defertest3.go
Jack Closed!!!
Lily Closed!!!
Done!


The use of such a method, depending on the unreasonable, but there is the need for existence. In most cases, it can be used in situations such as u1,u2 that consume very much memory, or the CPU, and then execute the time process without too many associations. It retains the functional characteristics of the defer and satisfies the conditions of precise control of the range!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.