Please indicate the source of the reprint without my consent.
The following is the content on the Internet plus my understanding. If there is any infringement, please notify me to delete the article.
What is a closure function?
First look at the code below to see if you know what it really means:
function test()
local i=0
return function()
i=i+1
return i
end
end
doTest=test()
print(doTest()) --Output 1
print(doTest()) --Output 2
You may have questions like this:
1. When you call the function doTest() returned by test(), what is the definition of variable i?
2. Is i not a local variable in test()?Why can the returned function be called?
If you have such a question, look down.
First, learn about several concepts:
Lexical bounds: When one function nests another function, the internal function can access local variables of the external function. This feature is called lexical bounds.These variables are called the upvalue of the embedded function, and upvalue actually refers to variables, not values, which can be shared among internal functions.
Closure: An instance function generated by calling an external function containing an internal function plus an external local variable (upvalue) held by the external function (the external function is the factory).
Closure composition: external function + upvalue + internal function created by external function (closure function)
As in the function test(), above,
test() is an external function.
The local variable local i=0 of an external function is upvalue (also known as a non-local variable, so called a non-local variable because the scope of this variable is neither the scope of a local variable nor the scope of a global variable).),
The function returned is an internal function.
Now looking back at the original function, we know that this form of function is called a closure function.The local variable i in test() is the upvalue (non-local variable) of the embedded function and is shared in the internal function.
When internal functions are called repeatedly, each call remembers the value after the last call, that is, after the first call to doTest(), the value of i is already 1.
Here's another example
function test()
local i=0
return function()
i=i+1
return i
end
end
doTest=test()
doAgain=test()
print(doTest()) --Output 1
print(doTest()) --Output 2
print(doAgain()) --Output 1
print(doAgain()) --Output 2
You can see that when doAgain() is executed, the i value does not increase from the original value.
As a result of:
doTest, doAgain, is built on the same function, two different closures on different instances of the same local variable.
A single call to test() results in a new closure, in which Upvalues are independent.Therefore, it is not difficult to explain why the i value of doAgain() has not increased from its original value.
What is the use of closure functions?
Iterators need to be used in loops for in, and iterators need to retain the state of the last call and the state of the next successful call, which can be done using the mechanism of closures.
Create an iterator:
function list_iter(t) --Outsourcing functions are called factory functions.
local i=0
local n=table.getn(t)
return function()
i=i+1
if i<=n then return t[i] end
end
end
--[[There list_iter Is a factory and each call results in a new closure.The closure includes upvalue(t,i,n).
//Therefore, every time the function is called, the closure will be returned to the next list based on the state of the last record.]]
In while:
--while Use:
t={10,20,90}
iter=list_iter(t) --Invoke iterator to produce a closure
while true do
--When closure function's i Value is already equal to n The closure function is still executed when the value of nil.
--If there is no judgement below, while It will go on and go into an endless loop.
local element=iter()
if element==nil then break end
print(element)
end
Using in generic for
--generic paradigm for Use:
t={10,0,29}
--There list_iter()Factory functions are called only once to produce a closure function.
--Each subsequent iteration uses the closure function, not the factory function.
for element in list_iter(t) do
print(element)
end
//If you want to return K and V values at the same time, you need to modify the factory function as follows:
function list_iter(tb)
local i = 0
return function ()
i = i + 1
--If there is no such judgment below, it will always be executed.
--See my other blog for more details. Lua Content About for Summary of Cycle
if tb[i] == nil then
return nil
end
return i,tb[i]
end
end