SoFunction
Updated on 2025-04-12

Closure Study Notes in Lua

Previous introductionLua's data typeIt is also mentioned that Lua's function is a "first-Class Value". It can:

Stored in a variable or table (e.g.ModuleandObject-orientedimplementation)

Copy the codeThe code is as follows:

t = { p = print }
("just a test!")

Passed as a real parameter (also called a "higher-order function") to other function calls

Copy the codeThe code is as follows:

t = {2, 3, 1, 5, 4}
(t, function(a, b) return (a > b) end)

As return value for other functions

Copy the codeThe code is as follows:

function fun1(x) return fun2(x) end

The feature of the function in Lua makes it a flexible and highly elastic data type, and at the same time, it also leads to some special and powerful language mechanisms:

Closure

Functions in Lua are the first type of values ​​with lexical scope, and can also be said to be the scope of function variables, that is, the variables of the function have a certain scope of utility, and variables can only be visible or accessed within a certain scope.

For example, the following code:

Copy the codeThe code is as follows:

function count()
    local uv = 0
    local function retfun()
        uv = uv + 1
        print(uv)
    end
    return retfun
end

The above function retfun is defined in the function count. Here, the function retfun can be regarded as the inner function of the function count, and the function count is regarded as the enclosing function of the function retfun. An inline function can access all local variables created by an outsourcing function. This characteristic is the lexical scope mentioned above, and these local variables (such as the variable uv above) are called external local variables or upvalues ​​of the inline function.

Execute function count:

Copy the codeThe code is as follows:

c1 = count()
c1()                 -- Output 1
c1()                -- Output 2

When you call c1 twice above, you will see outputs 1 and 2 respectively.

For a local variable uv in a function count, after executing "c1 = count()", its life cycle should end, but because it has become the external local variable upvalue of the inline function retfun, the returned inline function retfun saves the value of uv in the form of upvalue, so the value can be printed correctly.

This phenomenon of local variables continuing to exist after the function returns, and the returned function can call the local variable normally and perform its logical operations independently is called closure in Lua.

The reason why closures are independent individuals can be assigned to a variable, and then executed to see the output effect:

Copy the codeThe code is as follows:

c2 = count()
c2()

c1 and c2 are the same function body, but the output values ​​are different! This is mainly because the closure consists of references to the corresponding function prototype and external local variable upvalue. When the call of the function causes the upvalue value to be changed, this will only change the upvalue value of the corresponding closure and will not affect the upvalue value in other closures. Therefore, after c1 is called 2 times, the value of the external local variable uv is 2, while the initial external local variable uv of the newly created c2 is 0, and it will be 1 after being called.