Lua的函数定义,传参注意事项和返回值

常用内置函数

table.insert: 将 value 插入 list[pos],同时将后面的数值向后移动一位,如果没有指定 pos 添加到 list 尾部,post 默认为 #list+1。

table.insert (list, [pos,] value)

ipairs (t):迭代器,遍历数组:

for i,v in ipairs(t) do body end  -- ipaires(t) 返回  (1,t[1]), (2,t[2]), ...,

next:返回 table 中指定位置的元素。

next (table [, index])

声明定义

函数用关键字function定义,默认为全局的。

全局函数保存在全局变量中,会增加性能损耗,应当尽量使用局部函数,前面加上local:

local function function_name (arc)
  -- body
end

函数要定义后才能使用,定义代码在前面的。

可以函数定义时,直接设置为table的成员,如下:

function foo.bar(a, b, c)
    -- body ...
end

等同于:

foo.bar = function (a, b, c)
    print(a, b, c)
end

参数传递

非table类型的参数是按值传递的,table类型的参数传递的是引用。

调用函数时,如果传入的参数超过函数定义中的形参个数,多出的实参被忽略,如果传入的参数少于定义中的形参个数,没有被实参初始化的形参默认为nil。

变长参数用...表示,访问的时候也使用...

local function func( ... )                -- 形参为 ... ,表示函数采用变长参数

   local temp = {...}                     -- 访问的时候也要使用 ...
   local ans = table.concat(temp, " ")    -- 使用 table.concat 库函数对数
                                          -- 组内容使用 " " 拼接成字符串。
   print(ans)
end

table类型的参数按引用传递,可以在函数修改它的值:

local function change(arg)             --change函数,改变长方形的长和宽,使其各增长一倍
  arg.width = arg.width * 2      --表arg不是表rectangle的拷贝,他们是同一个表
  arg.height = arg.height * 2
end                              -- 没有return语句了

local rectangle = { width = 20, height = 15 }

change(rectangle)

函数返回值

函数是多值返回的:

local function swap(a, b)   -- 定义函数 swap,实现两个变量交换值
   return b, a              -- 按相反顺序返回变量的值
end

local x = 1
local y = 20
x, y = swap(x, y)    

接收返回值的变量数量少于函数返回的值的数量时,多出的返回值被忽略,大于的时候,多出的接收变量被设置为nil。

在多变量赋值的列表表达式中,如果多值返回的函数不在最后一个,那么只有它的第一个返回值会被接收:

local function init()       -- init 函数 返回两个值 1 和 "lua"
    return 1, "lua"
end

local x, y, z = init(), 2   -- init 函数的位置不在最后,此时只返回 1
print(x, y, z)              -- output  1  2  nil

local a, b, c = 2, init()   -- init 函数的位置在最后,此时返回 1 和 "lua"
print(a, b, c)              -- output  2  1  lua

注意函数的传入参数也是列表表达式,遵循同样的规则,如下:

local function init()
    return 1, "lua"
end

print(init(), 2)   -->output  1  2
print(2, init())   -->output  2  1  lua

列表表达式中,如果要确保函数只返回一个值,用括号将函数包裹:

local function init()
    return 1, "lua"
end

print((init()), 2)   -->output  1  2
print(2, (init()))   -->output  2  1

函数回调

函数回调时,用unpack处理传入的变长参数:

local function run(x, y)
    print('run', x, y)
end

local function attack(targetId)
    print('targetId', targetId)
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