The following column golang tutorial will introduce to you the meaning and usage of closures in golang. I hope it will be helpful to friends in need!
What is a closure?
Go function can be a closure. A closure is a function value that references a variable outside the function body. This function can access and assign values to the referenced variable; in other words, the function is "bound" to the variable.
My unreliable understanding, A closure is equivalent to an instance of a class, and variables outside the function body are equivalent to the variables stored in this instance.
When there is no closure, the function is a one-time transaction. After the function is executed, the value of the variable in the function cannot be changed (the memory should be released); with the closure, the function becomes The value of a variable, as long as the variable is not released, the function will always be alive and exclusive, so the value of the variable in the function can be changed later (because this way the memory will not be reclaimed by go, and it will always be cached in There).
The main significance of closure
Reduce the scope of variables and reduce the pollution of global variables. If the following accumulation is implemented using global variables, the global variables will be easily contaminated by others. At the same time, if I want to implement n accumulators, I need n global variables each time. Using the backpack, each generated accumulator myAdder1, myAdder2 := adder(), adder()
has its own independent sum, and sum can be regarded as myAdder1.sum and myAdder2.sum.
You can use the backpack to implement functions with their own states!
package mainimport ( "fmt")func adder() func(int) int { sum := 0 return func(x int) int { sum += x return sum }}func main() { myAdder := adder() // 从1加到10 for i := 1; i <= 10; i++ { myAdder(i) } fmt.Println(myAdder(0)) // 再加上45 fmt.Println(myAdder(45))}
Result:
55 // 1+...+10 100
Example
Use closure to implement Fibonacci sequence
package mainimport ( "fmt")func fibonacci() func() int { b0 := 0 b1 := 1 return func() int { tmp := b0 + b1 b0 = b1 b1 = tmp return b1 }}func main() { myFibonacci := fibonacci() for i := 1; i <= 5; i++ { fmt.Println(myFibonacci()) }}
Result:
1 2 3 5 8
Error-prone points
func B() []func() { b := make([]func(), 3, 3) for i := 0; i < 3; i++ { b[i] = func() { fmt.Println(i) } } return b}func main() { c := B() c[0]() c[1]() c[2]()}
Result:
// 因为都引用i,i最后变成了3 3 3 3
Correction method 1:
package mainimport ( "fmt")func B() []func() { b := make([]func(), 3, 3) for i := 0; i < 3; i++ { j := i b[i] = func() { fmt.Println(j) } } return b}func main() { c := B() c[0]() c[1]() c[2]()}
Correction method 2:
package mainimport ( "fmt")func B() []func() { b := make([]func(), 3, 3) for i := 0; i < 3; i++ { b[i] = func(j int) func(){ return func() { fmt.Println(j) } }(i) } return b}func main() { c := B() c[0]() c[1]() c[2]()}
For more related technical articles, please visit the go language tutorial column!
The above is the detailed content of Do you know the meaning and usage of closures in golang?. For more information, please follow other related articles on the PHP Chinese website!