Lua 函数学习笔记
函数定义与调用
在 Lua 中,函数可以被定义并保存在变量中,也可以被直接定义并调用。以下是两种定义函数的方式:
luaCopy Code-- 保存在变量中
local function add(a, b)
return a + b
end
-- 直接定义和调用
print(function(a, b) return a + b end(2,3)) -- 输出 5
使用 function
关键字来定义函数,函数名可以省略,形参列表包含在一对小括号中,函数体则包含在 end
关键字之前。
函数调用时,使用函数名加上一对小括号并在其中传递实参即可。如果函数只有一个参数且该参数是字符串或表构造式,则可以省略小括号。
多重返回值和可变参数
Lua 函数允许返回多个值,这些值可以是任何类型。多个返回值可以通过元组的方式接收,也可以通过下标的方式获取某个具体返回值。
luaCopy Code-- 返回多个值
function swap(a, b)
return b, a
end
x, y = swap(1, 2)
print(x, y) -- 输出 2 1
-- 可以忽略部分返回值
x = {swap(1, 2)}
print(x[1]) -- 输出 2
此外,函数还支持可变参数。使用 ...
表示可变参数,在函数内部,它被视为一个包含所有传递的实参的数组。
luaCopy Code-- 可变参数
function sum(...)
local res = 0
for i, v in ipairs{...} do
res = res + v
end
return res
end
print(sum(1, 2, 3, 4)) -- 输出 10
匿名函数和闭包
Lua 支持匿名函数,也叫 lambda 函数。与普通函数一样,匿名函数也可以被保存在变量中,也可以被作为实参传递给其他函数。
luaCopy Code-- 匿名函数
local add = function(a, b) return a + b end
print(add(1, 2)) -- 输出 3
匿名函数可以使用外部变量,这就引入了闭包的概念。闭包是指一个函数加上其所使用的外部变量所组成的整体。
luaCopy Code-- 闭包
function outer()
local a = 0
return function()
a = a + 1
return a
end
end
local f1 = outer()
print(f1()) -- 输出 1
print(f1()) -- 输出 2
local f2 = outer()
print(f2()) -- 输出 1
在以上示例中,函数 outer
返回了一个匿名函数,该匿名函数使用了 outer
中的局部变量 a
,每次调用都会将 a
增加 1。由于 f1
和 f2
都是 outer
返回的不同函数,它们各自维护着一个独立的 a
,因此 f1
和 f2
的调用互不干扰。
实例:计算表达式的值
以下是一个简单的示例,展示了如何使用 Lua 函数来计算表达式的值。
luaCopy Code-- 计算表达式的值
function eval(expr)
local stack = {}
for token in string.gmatch(expr, "%S+") do
if tonumber(token) then
table.insert(stack, token)
else
local a = table.remove(stack)
local b = table.remove(stack)
if token == "+" then
table.insert(stack, b + a)
elseif token == "-" then
table.insert(stack, b - a)
elseif token == "*" then
table.insert(stack, b * a)
elseif token == "/" then
table.insert(stack, b / a)
end
end
end
return stack[1]
end
print(eval("1 2 +")) -- 输出 3
print(eval("5 3 - 4 +")) -- 输出 6
以上示例中,eval
函数将传入的字符串表达式按空白符分割成多个单词,并根据运算符将数字和符号加入到一个栈中。最后通过栈顶元素得到计算结果。注意,在计算时先出栈的是被减数和被除数,而不是一般的左操作数。