Defer and Closure in Go

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

Learn about defer-related knowledge in Go and the concept and usage of closures.

Defer's understanding

According to the official explanation, the expression after defer is placed in a list, and the expression in the list is executed when the current method returns. A method can use the defer expression in one or more places. An example in the documentation is as follows:

  func    a   ()    {   i        :=    0    defer    fmt    println   ( i  )    //defer FMT. PRINTLN (2)    //defer FMT.    PRINTLN (3)    i  ++    return    }     

The printed value is 0, which is very surprising, even if the final execution according to defer, then the value of I should be 1 ah. Carefully read the official document The original reason: The above code, the defer expression used in the I variable, I after the initialization of the value of 0, then the program executes to the defer expression line, the expression uses the value of I is 0, and then the expression is placed in the list, wait for the return is called when the So, although there is a i++ statement in the back, it still cannot change the expression FMT. Results of Println (i). We then add the annotated code to the above code, and the result is 3,2,0. This verifies thatthe order in which the defer expression is called is in the advanced, post-out manner .

The named return value in the function can be modified in the defer expression, as shown in the following code:

func c() (i int) {    defer func() { i++ }()    return 1}

The return-value variable is named I, and the value of the variable can be modified in the defer expression. So, although the return value is assigned a value of 1 when it is returned, later defer modifies the value to allow I to increment by 1, so the return value of the function is 2 instead of 1. This can explain the question in the code below.

anonymous functions

Once we don't want to give a name to a function for the time being, you can define the function in the following way:

func(x, y int) int { return x + y }

The corresponding invocation method is as follows, note the last pair of parentheses, which is the invocation of the anonymous function :

func(x, y int) int { return x + y } (3, 4)

The following example shows how to assign an anonymous function to a variable and invoke it:

 Package MainImport "FMT"func Main() {    F()}func F() {     for I := 0; I < 4; I++ {      ///anonymous function assignment to local variable g        g := func(I int) { FMT.Printf("%d", I) }         //Using variables to invoke anonymous functions      g(I)        FMT.Printf("-G is of type%T and have value%v\ n", g, g)    }}

The book further gives us an example of the following, the anonymous function is combined with defer:

 Package MainImport "FMT"//Question onefunc F() (ret int) {    defer func() {        ret++    }()    return 1}func Main() {    FMT.Println(F())}

The final return is 2, because RET + + occurs after the return 1 statement is executed. In fact, the individual is a bit puzzled, return returns the number, is to give RET as the initial variable? Or the statement returned by return immediately enters into the function defined by defer?

Closures and functions

function is just a piece of executable code, after compiling "cured", each function in memory only one instance, get the function entry point can execute function. In a functional programming language, a function is a first-class citizen: A primary object, we do not need a function pointer, as in imperative language, a delegate action function, a function can be a parameter or a return value of another function, can be assigned to a variable. Functions can be nested defined, that is, within one function can define another function, with the structure of nested functions, the closure problem arises. At this point, you need to be aware that closures are not functions. Because of the context of closures, which is a reference environment, different reference environments can be different instances of the same closure. In OO, we are accustomed to the transmission of the object , and in functional programming, we need to change the idea, we came to pass is the function .

Apply closures: Use functions as return values

The following two functions, ADD2 and Adder, return functions that are signed as func (b int) int:

func Add2() (func(b int) int)func Adder(a int) (func(b int) int)

The corresponding instance is as follows:

 Package MainImport "FMT"func Main() {    Add2 function, give it a name P2, and call it:    P2 := ADD2()    FMT.Printf("Call ADD2 for 3 gives:%v\ n", P2(3))    //Make a special Adder function, a gets value 3:    Twoadder := Adder(2)    FMT.Printf("The result is:%v\ n", Twoadder(3))}//function as the return valuefunc ADD2() func(b int) int {  //Note the structure here    return func(b int) int {        return b + 2    }}func Adder(a int) func(b int) int {    return func(b int) int {        return a + b    }}

The values returned are as follows:

 Call Add2 for 3 gives: 5  The result is: 5

Then a more important example is given in the book, which shows us a concept: The closure function saves and accumulates the values of the variables, and it can continue to manipulate local variables in the external function regardless of whether the external function exits or not.

Examples are as follows:

 Package MainImport "FMT"func Main() {    var F = Adder()    FMT.Print(F(1), " - ")    FMT.Print(F( -), " - ")    FMT.Print(F( -))}///Adder () function, function as return valuefunc Adder() func(int) int {    var x int  //Closure function, for continuous return with simple thinking to understand    return func(Delta int) int {        x += Delta        return x    }}

According to the general thinking, will certainly feel the return value: 1-20-300. The results that can be executed by the program are: 1-21-321. This? Let's think it through: three calls to function f the value of the variable delta in the function Adder () is: 1, 20, and 300, respectively. Comparing the results of the output, we find that each time the local variable of the external function is not cleared in the closure 0!!! , which means that the value of the variable x is preserved in the closure . Regardless of the state of the external function!!!

Also note that the variables used in closures can also be declared outside the closure function body in the closure function body .

Calculate function Execution Time

The last section in this chapter describes how to calculate the execution time of a function, mainly the now () and Sub () functions in the Times package, and for function optimization, we can compare them by the calculation time of the function:

Start :=  Time. Now()longcalculation()End :=  Time. Now()Delta := End.Sub(Start)FMT.Printf("Longcalculation took this amount of time:%s\ n", Delta)
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.