最近这两天出差了,学习任务被搁下了实在是不应该。不说了,抓紧学习!
这一次要说一下lua的函数跟动态函数。
之前学类型的时候也学习过,函数在lua中也是一种类型,可以进行赋值。所以就有了
function_name = function (arc)
-- body
end
其实等价于
function function_name (arc) -- arc 表示参数列表,函数的参数列表可以为空
-- body
end
这是一个全局函数,由于全局变量一般会污染全局名字空间,同时也有性能损耗(即查询全局环境表的开销),因此我们应当尽量使用“局部函数”,其记法是类似的,只是开头加上 local 修饰符。
由于函数定义等价于变量赋值,我们也可以把函数名替换为某个 Lua 表的某个字段,例如
function foo.bar(a, b, c)
-- body ...
end
此时我们是把一个函数类型的值赋给了 foo 表的 bar 字段。换言之,上面的定义等价于
foo.bar = function (a, b, c)
print(a, b, c)
end
对于此种形式的函数定义,不能再使用 local 修饰符了,因为不存在定义新的局部变量了。注意此时的foo是一个table类型,而foo.bar则是一个函数变量,是不是很酷。foo就像个类,而foo.bar就像是一个类方法一样。
还有一点很重要的就是lua的函数是可以返回多个值的
local function swap(a, b) -- 定义函数 swap,实现两个变量交换值
return b, a -- 按相反顺序返回变量的值
end
local x = 1
local y = 20
x, y = swap(x, y) -- 调用 swap 函数
print(x, y) --> output 20 1
它并不像C++那样需要把其它的返回值以引用的形式传到函数中来,直接可以返回多个值,这样代码的可读性就可以好很多。
而且Lua还有一个很酷的功能,支持动态函数:
local function run(x, y)
print('run', x, y)
end
local function attack(targetId)
print('targetId', targetId)
end
local function receive()
print('receive nothing')
end
local function do_action(method, ...)
local args = {...} or {}
method(unpack(args, 1, table.maxn(args)))
end
do_action(run, 1, 2) -- output: run 1 2
do_action(attack, 1111) -- output: targetId 1111
do_action(receive) -- output: receive nothing
就像c++的函数模版一样,但是使用起来更加方便跟易读。其中args是动态函数的参数,{…}是多个参数,{}是无参数。如果把{…}删除掉,那么输出就会变成这样:
run nil nil
targetId nil
receive nothing
可是如果把{}删掉,则输出是正常的,说明{…}是包含{}的。