OpenResty学习笔记(二)函数,


最近这两天出差了,学习任务被搁下了实在是不应该。不说了,抓紧学习!
这一次要说一下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

可是如果把{}删掉,则输出是正常的,说明{…}是包含{}的。

相关内容

    暂无相关文章