函数 - abbshr/Lua-newbie GitHub Wiki
基本结构:
function name (arg_list)
...
end
调用:name(arg)
Note:如果参数只有一个,且是字符串或table类型时,函数调用的括号可选
Note:lua使用的函数可以是lua编写的也可以是其他语言编写的.
Note:行参与实参的匹配与赋值语句类似:多删少补nil
多个返回值:
在return后列出要返回的值的列表,即可返回多值。
ex:
function leader (tb)
local leadlist = {}
for name, level in pairs(tb) do
if level == "leader" then
leadlist[name] = level
end
end
return leadlist, tb
end
Note:lua会根据调用环境调整函数返回值
-
作为表达式调用函数
- 如果函数调用作为表达式的最后一个参数或唯一一个参数时,根据变量个数函数尽可能多的返回值,多删少补nil原则
- 其他情况下,函数调用仅返回第一个值(如果没有返回值则返回nil)
-
作为函数参数被调用
-
在table中初始化
-
作为函数的返回值调用
Note:可以使用圆括号强制函数调用返回一个值
ex:
function foo () end
print(foo()) --
print((foo())) -- nil
unpack()函数,接受一个数组,返回数组的所有元素。
Lua版实现:
function unpack(t, i)
i = i or 1
if t[i] then
return t[i], unpack(t, i + 1)
end
end
可变参数
function name (a, b, ...)
arg = {...}
end
闭包、词法作用域、高级函数
函数表达式写法: foo = function () end
说明函数是第一类值。闭包概念基本等同JS
作为table内函数,三种写法:
tb = {}
tb.foo = function () end
ab = {
foo = function () end
}
fb = {}
function fb.foo() end
局部函数:
local foo = function () end
local function foo() end
局部函数的递归:
如果按这种方式写:
local fact = function (n)
if n == 0 then
return 1
else
return n*fact(n-1)
-- buggy
end
end
print(fact(5)) --这里会报错,lua会认为fact是全局函数,结果找不到它
为解决这个问题,第一种方法首先声明fact:
local fact
fact = function (n)
if n == 0 then
return 1
else
return n*fact(n-1)
-- buggy
end
end
print(fact(5))
第二种方法:
local function fact(n)
if n == 0 then
return 1
else
return n*fact(n-1)
-- buggy
end
end
print(fact(5))
Note:没有类似JS中变量的提升
local f, g
function f() g() end
function g() f() end
f()
-- 如果写成如下,则会抛出错误:g被看作全局变量
local function f() g() end
local function g() f() end
f()
说明g的声明并没有被提升
尾调用(包含尾递归)
函数的最后一个动作是调用一个函数,称这种调用为尾调用。因为父函数在尾调用后不会再做任何事情,因此栈中不需要保留其信息。
尾递归的层次可以无限,因为无需额外的栈空间,不会导致栈溢出。
function foo()
return foo()
end
但如果这样写则会导致stack overflow:
function foo()
foo()
end
下面这些同样不是尾递归:
return fact() + 1
return (fact())
return x or fact()
fact()
return