在Lua中函数和其他类型的值具有相同权利,如函数和数值、字符串等具有相同地位。因此函数也可以像其他类型一样存储到变量、table(对象)中,也可以作为参数传递到其他任意函数中,同时也可以作为返回值从函数中返回。
- 函数存储在变量中
print(print)
-->> function: 00000000684989c0
local p = print
print(p)
-->> function: 00000000684989c0
函数可以存储在变量中,print
和p
都指向了同一个函数。
print(123)
p(123)
local t = {p = print, a = math.abs}
print(t.p(t.a(-98)))
print(123)
和p(123)
结果一致,表示发起了函数调用,这也说明函数可以存储到变量中。实际上函数名就是一个变量,比如print
就是一个打印的函数变量,并不是函数本身。
p = print
print = math.abs
p(print(-9))
-->> 9
print = p
print(-9)
-->> -9
将math.abs
函数指向print
时,并且之后的测试中可以看出,系统中的print
只是指向打印函数的变量,并不是函数本身,print
可以再次被赋值,指向其他数据类型或新的函数,并且不影响打印函数本身。当再次指向p
时,其又恢复了原始功能。
- 函数可以作为参数传入函数
从上面可以看出变量可以指向函数,在访问指向函数的变量时,可以获得函数的同等功能;而变量可以作为实参传入函数,那么就可以将指向函数的变量,传入一个函数中。
接收两一个函数作为实参的函数称为高阶函数
function add(a, b, f)
return f(a) + f(b)
end
print(add(-9, -8, math.abs))
-->> 17
local total = add(7, -3, function(a)
return a * 2
end)
print(total)
-->> 8
- 函数可以嵌套在另外一个函数中
Lua不仅可以在函数中嵌套新的函数,同时嵌套的函数还可以访问外部变量。
local nums = { 1, 2, 3, 4, 5 }
function add(a)
b = function()
local t = 0
for i, v in pairs(nums) do
t = t + v
end
return t
end
print(a .. "calc is :" .. b())
end
add("nums")
-->> numscalc is :15
对于Lua,定义的函数其实都是使用
function()
进行定义的,函数定义完成后,将其指向了变量,如本例中的内部函数b
。从这个例子中,也能够证明前面所说的函数名本身只是指向函数的变量,并不是函数本身。
嵌套的函数还可以作为结果从函数中返回。
function worker(numbers)
return function()
total = 0
for i, v in pairs(numbers) do
total = total + v
end
return total
end
end
sum = worker({1,2,3})
print("结果=" .. sum())
-->> 结果=6
在这个例子中,返回了一个新的函数,只有在调用该函数的时候,才执行了真正的数组累加,营造了一种延迟执行的现象,当返回一个函数时,将相关的数据都保存在函数中返回,这种行为称为闭包
。