Closure (closure) and coroutine should pay attention to the things, closure
Closures are a small technique that allows you to program in a very comfortable way. Go also supports closures. If you have never touched a closure, it is very difficult to understand what it is at the beginning, just like recursion, until you have actually written and used it, so that you can have a more specific understanding of it.
A closure is a function that contains the context environment required to run it. This environment may be several variables or may be others (usually variables ). The closure is a function that is incorrect. More specifically,A closure is a runtime environment that packages the external context environment of its scope.. It doesn't matter if you haven't understood the meaning of this closure for a while. This is a step-by-step process.
Let's look at an example of the most common online closure explanation:
Package mainimport "fmt" func A () func () int {value: = 0 return func () int {value ++ return value} // () at this point, the local variable value} func main () {B: = A () fmt should have been destroyed. println (B () fmt. println (B () fmt. println (B ())}
The running result is:
123
Let's take A good look at this code. We define A function A (). In A, we define another function B (), and B will return it to us as the return value. The role of B is to increase the value of A's local variable by 1 each call. However, after function A runs, it is reasonable to say that the value of the local variable has been destroyed, and B cannot operate on it. However, from the running result, the value is still "alive ". Yes, this is the so-called function that packs the Context Environment. B is A closure function, which not only defines its own operation flow, but also includes its value variable in Environment A above.
In this example, you may not see the function of the closure, but in fact, the closure is more or less required that the programming language support anonymous functions and the function is the first type in the Chinese language (you can assign a function to a variable and use the function as a parameter and return value ). I am not very familiar with the function of closures. Using closures in languages with many defects such as JS can bring the benefits of protecting variable access permissions and better modularity. For Go, I think the biggest benefit of closures is:
1. You don't need to name a function ~
2. A temporary function can be defined in the nearest place.
3. you can directly use go func (){...} () in this way, you do not need to pre-define every function to be concurrent outside the current runtime environment.
After finishing the basic content of the closure, let's talk about the issues that should be paid attention to when using the closure. In principle, the biggest advantage of using a closure isConvenientBut do not always think of using closures in any case, because if you do not know about closures, the code you write may have unexpected running effects. Let's take a look at the following example:
Package mainimport ("fmt") func main () {done: = make (chan bool, 3) for I: = 0; I <3; I ++ {go func () {// There is a problem here. Each routine packages the variable ifmt in the outer running environment. println (I) done <-true} ()} for I: = 0; I <3; I ++ {<-done }}
The running result is:
333
If you look at the code carefully, you should feel that the Code does not seem to have any problems. But what is the result of 1 2 3 ??? In fact, the Go official guide also provides related examples for developers to pay attention to this issue when using closures and goroutine.
In this example, the three goroutines In the first loop do not run immediately after they are created,Because they are bound to the variable I in the outer runtime environment, because the outer runtime environment changes the I value at any time, the three routine cannot start to run because the loop ends..
The solution is to pass the outer context to the closure function as a parameter, as shown in the following code:
Package mainimport ("fmt") func main () {done: = make (chan bool, 3) for I: = 0; I <3; I ++ {go func (index int) {// pass I in the outer environment as a parameter to fmt. println (index) done <-true} (I) // pass I in} for I: = 0; I <3; I ++ {<-done }}
In this case, the closure function does not need to bind the variable I in the outer environment. This issue must be noted because the goroutine and closure are often used together in Go. If context packaging is not properly handled, unexpected running results may occur.
If reproduced, please indicate the source: http://blog.csdn.net/gophers
What is Closure )? Answer
This article is translated. This problem was raised in the last Brighton ALT. NET Beers event in England. I found that if you do not need code to demonstrate it, it is difficult to explain it clearly in words. So here, I plan to use C # To explain what closures is ). In computer science, Closure is short for Lexical Closure, a function that references free variables. This referenced free variable will exist with this function, even if it has left the environment where it was created. Therefore, there is another saying that a closure is an entity composed of a function and its reference environment. Therefore, a closure is a function that "captures" or "carries" all variables referenced in the scope of variables in the generated environment. Indeed, it is hard to describe, but it is easy to understand after you have read the code. Var x = 1;
Console. Out. WriteLine ("result = {0}", result) ;}; action (); here we first define a variable "x" with a value of 1. Then we define an anonymous function (a lambda expression) assigned to the type Action. Action has no parameters and no return value. However, if you observe the definition in "action", you will find that it uses the "x" variable. This variable is "captured" or "carried" by the action and is automatically added to the runtime environment of the action. When we execute the action, It outputs the expected results. Note that the original "x" is out of its original variable environment, but it can still be used. When you observe "action" in the Code debugger, you will find interesting things. We can see that the C # compiler creates a Target class for us, which encapsulates the x variable: closure (and higher order functions. If you have developed a Javascript program that is a little more complex, you may know that it can be used as a substitute for many object-oriented features, just like C. Not long ago, I wrote an example in C # To verify this idea. Traditionally, John Skeet gives the closure a more detailed description. For more details, see this chapter in in-depth analysis of C. It also introduces some errors you may encounter in closures. Read: C # What is a closure with a closure? I understand it.
Three small issues with VC ++ // closure_operationcpp -- closure operation