closure
concept
Closure function: a function declared in a function, called a closure function.
Closure: an internal function always has access to the parameters and variables declared in the external function in which it resides, even after its external function has been returned (end of life).
Characteristic
Make it possible for external access to function internal variables;
Local variables are resident in memory;
It can avoid the use of global variables and prevent the pollution of global variables;
Can cause memory leaks (a block of memory space is occupied for a long time without being released)
Closure creation
Closure is to create an independent environment. The environment in each closure is independent and does not interfere with each other. There will be a memory leak in the closure. * * each time the external function executes, the reference address of the external function is different, and a new address will be created again. **However, if the data in the current active object is referenced by an internal subset, at this time, the data will not be deleted and a
Closure example
Example 1
- Returns an intrinsic function
package main import "fmt" //Function segment func add(base int) func(int) int { // 1: Create a new memory, and name it base to store int variables. Then take the value stored in a memory, copy it and put it in base memory fmt.Printf("%p\n", &base) //2: Print variable address 0xc0420080e0, which stores 10 [it is the function copy value] f := func(i int) int { //3: Define a function and use f to point to it [f stores the address of this function] //7. Store 1 in i fmt.Printf("%p\n", &base) // 2: Print variable address 0xc0420080e0 base += i // Take out the value stored in the base + the value stored in the i, and then put the result into the base for storage return base //Return the value stored in the base } return f // 4: Return function address f } func main() { aa := 10 fmt.Printf("a Address:%p\n", &aa) //0xc0420080a8 t1 := add(aa) //5. Store the function address returned by add(a) with a t1 c := t1(1) //6. Call the function pointed to by t1, pass the parameter as 1 [pass the value], and then store the returned result in the new memory c fmt.Println(c, &c) //11 0xc0420540b0 fmt.Println(t1(2)) // 13 T1 still points to the original open space. At this time, base=11, so 11 + 2 t2 := add(100) //Open up a new space to call add(100), and then store the returned function address with a t2. At this time, base is the newly established fmt.Println(t2(1), t2(2)) }
- Returns multiple intrinsic functions
package main import "fmt" //Return the addition and subtraction function, important: reference to external variable when internal function func calc(base int) (func(int) int, func(int) int) { fmt.Printf("%p\n", &base) add := func(i int) int { fmt.Printf("%p\n", &base) base += i return base } sub := func(i int) int { fmt.Printf("%p\n", &base) base -= i return base } return add, sub } //Starting from main function as program entry point func main() { f1, f2 := calc(11111) fmt.Println(f1(1), f2(1)) //Execution sequence: f1 f2 println }
Example two
When goroutine is involved, the program fragment is as follows:
package main import ( "fmt" "time" ) //Starting from main function as program entry point func main() { for i:=0; i<5; i++ { go func(){ fmt.Println(i) //The value of the i variable is also a reference. Create 5 thread execution functions. When the execution of the for loop may be completed, the thread just benefits a certain value of i. }() } time.Sleep(time.Second * 1) }
Every time the program runs, the results are different
Code improvements:
package main import ( "fmt" "time" ) func main() { ch := make(chan int, 1) for i:=0; i<5; i++ { go func(){ ch <- 1 fmt.Println(i) }() <- ch } time.Sleep(time.Second * 1) }
Will block waiting: 0-4 value must have
Reference resources: https://blog.csdn.net/li_101357/article/details/80196650
Example three:
package main import "fmt" func funA() func(){ var a = 10; return func (){ fmt.Println(a); // Value stored at printing place a } } func main() { var b = funA() //funA() returns a function address, executes a function, and saves the address with b. at this time, b points to the function b() // Call the function pointed to by b }
Example 4: global variable VS closure function
package main import "fmt" func Outer() func(){ var i = 0; return func() { i++; fmt.Println(i) } } func main(){ var c = Outer() c() c() c() var d = Outer() d() d() d() } // 1 2 3 1 2 3
- Global function
package main import "fmt" var i = 0; func Outer() func(){ return func() { i++; fmt.Println(i) } } func main(){ var c = Outer() c() c() c() var d = Outer() d() d() d() } // 1 2 3 4 5 6
Example six
package main import "fmt" func Outer() func() int{ var i = 0; return func() int{ i++; return i; } } func main(){ c := Outer() // Returns a function fmt.Println(c()) //1 call the internal function, copy the value of i, and return fmt.Println(c()) //2 call the internal function, copy the value of i, and return d := c // c stores the function address. c places the stored function address in d. at this time, d and c point to the same function fmt.Println(d()) //3 call the internal function, copy the value of i, and return fmt.Println(d()) //4 call the internal function, copy the value of i, and return e := Outer() // A new memory is created to call functions. e stores the address of this memory fmt.Println(e()) //1 call the internal function, copy the value of i, and return fmt.Println(e()) //2 call the internal function, copy the value of i, and return fmt.Println(Outer()) //0x496a30 fmt.Println(Outer()()) //1 }