闭包

闭包就是能够读取其他函数内部变量的函数,在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数”。

C#闭包

  • 闭包是一个代码块(在C#中,指的是匿名方法或者Lambda表达式,也就是匿名函数),并且这个代码块使用到了代码块以外的变量,于是这个代码块和用到的代码块以外的变量(上下文)被“封闭地包在一起”。
  • 当使用此代码块时,该代码块里使用的外部变量的值,是使用该代码块时的值,并不一定是创建该代码块时的值。
  • 正常的函数内部的变量是保存在帧栈中(call stack>record Frame)。
  • 当形成闭包以后托管堆就形成一个类用来存放该变量
  • 一句话概括,闭包是一个包含了上下文环境的匿名函数。
//闭包中内层的函数可以引用包含在它外层函数的变量,即使外层函数的执行已经终止
//该变量提供的值并非变量创建时候的值,而是在父函数范围内的最终值
class Test
{
    public event Action action;
    //构造函数
    public Test()
    {
        //value如果没有下面的引用,应该在执行完构造函数就被gc掉
        int value = 10;
        //这里就形成了闭包,因为当构造函数执行后,其中申明的临时变量value的生命周期被改变了
        action = () =>
        {
            Console.WriteLine(value);
        }
        //该变量提供的值并非变量创建时候的值,而是在父函数范围内的最终值
        for (int i = 0; i < 10; i++)
        {
            action += () =>
            {
                Console.WriteLine(i);
            }
		}
    }
    public void DoSomething()
    {
        action();
    }
}
//执行DoSomething(),外部输出11个10

Lua闭包

--嵌套函数
function fun9(x)
	-- 在函数内部再声明一个函数,会改变外部函数传入参数的生命周期,从而产生了一个闭包
	-- 此处x的生命周期就被延长了
	return function(y)
		print(x + y)
	end
end
fun10 = fun9(5)  -- 此处传入的5的生命周期被延长了,在fun10中仍需要使用
fun10(2)  
-- 输出7

资料参考

https://www.bilibili.com/video/BV1Ar4y1K7AK?p=16

https://www.bilibili.com/video/BV1iA411n7oQ?p=8

https://www.cnblogs.com/cdaniu/p/15352317.html

https://zhuanlan.zhihu.com/p/376927953