Lua: Understanding closures and simple use

Preface: This article was created by me reading books and reading blogs. I will try my best to explain it in an easy-to-understand way. If there is something in the article that you think does not meet the standards, you are welcome to point it out and discuss it.

Concept: When a function is nested within another function definition, the internally defined function body can access the local variables of the external function; simply speaking, the closure is a function plus the upvalues ​​(local variables of the external function) that it can correctly access. .

如果你没看懂上面的概念的话先不用深究,继续往下看,看完这篇文章后再回来理解这句话。

To understand the above concept, you must first understand a few small concepts:Internally defined function body,. Local variables of external functions

    function test()
        local i=0;				--外部函数的局部变量  (也就是upvalue)
        
        return function()		--内部定义的函数体 
            i=i+1;
            print(i);
        end
        
    end

	c1=test();
	c1();

In the above code block, the return value of the test method is a function body, in this caseThe local variable i of the test method is called inside the function body. This phenomenon is called closure. The method stored in c1 is the closure in the test method (I don’t know if this description is correct, but you know what I mean, just understand it).

My understanding of the concept: When the return value of a function is afunction body, and the function body calls the function internally When a declared variable or parameter of this function is used, the return value of this function is a closure.
Running results:

>lua -e "io.stdout:setvbuf 'no'" "6.16.lua" 
1
>Exit code: 0

What is stored in c1 is the return value of the test method. The test method has ended execution, but its return value c1 also calls the value of the local variable i of the test method. In Lua's closure mechanism, this variable will be in the closure It is stored in and the value of this variable after running will be recorded. That is, when the call is made, this variable stores the value after the last call is executed.

    function test()
        local i=0
        return function()
            i=i+1;
            print (i);
        end
    end

	c1=test();

	c1();	--第一次执行时i的值是0,执行结束之后i的值是1c1();	--所以第二次执行这个方法时,i的值是1,执行结束之后i的值是2...以此类推;
	c1();
	c1();
	c1();

Results of the:

>lua -e "io.stdout:setvbuf 'no'" "6.16.lua" 
1
2
3
4
5
>Exit code: 0

Use closures to implement iterators

  • That is to traverse the elements in the collection, and each execution will call the next element in the collection. (You can refer to relevant information for the specific concept of iterators. Here is a simple example)
list_1={
    
    1,2.3,4,5,6,7,8};

function forList(list)
	local n=1;
	local maxN=table.getn(list);
	return function()						--这是一个闭包
		if n<=maxN then print(list[n]) end	
		n=n+1;								--每次调用都会将n的值+1也就是每次调用都会输出集合中的下一个元素
	end
end

lis=forList(list_1);

lis()
lis()
lis()
lis()
lis()

Results of the:

>lua -e "io.stdout:setvbuf 'no'" "6.16.lua" 
1
2.3
4
5
6
>Exit code: 0

Summary: The key is that there is a mechanism in the closure for upvalue to store the results of the last execution, so that the next element in the set can be output every time it is called.

Guess you like

Origin blog.csdn.net/u011229164/article/details/106808539