核心概念:什么是闭包?
简单来说,闭包是一个可以访问并"记住"其创建时所在作用域中变量的函数。
你可以把它想象成一个函数,它"随身携带"着它出生时的环境。这个环境是私有的,只有这个闭包自己可以访问。
闭包是如何产生的?
闭包的产生与 Lua 的 词法作用域 密切相关。
- 词法作用域:一个函数可以访问其定义时所在作用域内的变量,而不仅仅是它被调用时所在的作用域。
当一个函数内部定义了另一个函数,并且这个内部函数引用了外部函数的局部变量时,闭包就形成了。
一个简单的例子
让我们看一个最经典的计数器例子:
Lua
function createCounter()
local count = 0 -- 外部函数的局部变量
-- 内部函数(即将成为闭包)
local function increment()
count = count + 1 -- 引用了外部变量 count
return count
end
return increment -- 返回这个内部函数
end
-- 使用闭包
local myCounter = createCounter()
print(myCounter()) -- 输出:1
print(myCounter()) -- 输出:2
print(myCounter()) -- 输出:3
local myAnotherCounter = createCounter()
print(myAnotherCounter()) -- 输出:1 (全新的计数器,拥有独立的 count)
配置不同功能的闭包
Lua
function createMultiplier(multiplierFactor)
-- multiplierFactor 是外部函数的参数,也是局部变量
local function multiply(number)
return number * multiplierFactor
end
return multiply
end
-- 创建两个不同的乘法器
local double = createMultiplier(2)
local triple = createMultiplier(3)
print(double(5)) -- 输出:10 (5 * 2)
print(triple(5)) -- 输出:15 (5 * 3)
print(double(10)) -- 输出:20 (10 * 2)
用闭包实现ipairs 迭代器
Lua
t1={1,2,"hjk",4,5};
function mypairs(mytable)
local number=0;
local length=#mytable;
function mypairs_son()
if(number<length)then
number=number+1;
return number,mytable[number];
end
end
return mypairs_son;
end
for key, value in pairs(t1) do
print(key,value);
end
print("");
for key, value in mypairs(t1) do
print(key,value);
end
运行结果:
Lua
1 1
2 2
3 hjk
4 4
5 5
1 1
2 2
3 hjk
4 4
5 5