函数定义以function关键字开始,后面是函数名称,然后是传递给函数的参数列表。以end关键字结尾
传入参数
单一参数
函数中的参数是局部变量,在调用结束时回收
function SetName(myString)
print(mtString)
end
多个参数
多个参数之间使用 逗号 隔开
function SetName(myName,myAge) print(myName) print(myAge) end
可变长参数
使用 … 代替参数列表
- 在函数中使用{…}来获得这个参数列表
- Lua会创建一个局部的名字为arg的table,保存所有调用时传递的参数
- 参数个数使用arg=table.pack(…);arg.n获取
- 开发过程中加入注释,以防忘记函数需要多少个参数
- 还可以结合一些必要的参数,但是必须在可边长参数之前。如:myFunction(val1,val2,…)
- …:可变长表达式,可以认为是一个多返回值的函数
- print(…):打印…中的所有参数
```lua
function HowMany(…)
arg=table.pack(…)
for index = 1, arg.n do
end else print(“no value”) end endprint(arg[index])
- print(…):打印…中的所有参数
```lua
function HowMany(…)
function HowMany(val1,,val2,…)
if (arg.n > 0) then
for index = 1, arg.n do
print(arg[index])
end
else
print(val1+val2)
end
end
<a name="FDHop"></a>
#### select():遍历可边长参数
- **select(selector,...)**:返回**selector位置后**的所有**参数**
- selector:开始遍历的位置,使用**"#"**则代表**输出参数个数**
```lua
print(select("#",1,2,3,4,6)) --输出:5
print(select("2",1,2,3,4,6)) --输出:2 3 4 6
print(select("3",1,2,3,4,6)) --输出:3 4 6
返回值
- 将处理的结果返回到被调用的脚本。函数使用 return 变量 来返回
- 还可返回多个结果
- 函数被直接用于加法运算时,只返回第一个
- 在表达式中,多返回值函数必须是最后一个,否则也
- 使用(function())那么永远只得到第一个返回值 ```lua function back() return 1, 2 end
x, y, z = 0, back() —多返回函数时最后一个,返回多个返回值 print(x, y, z) —输出:0 1 2 a, b, c = back(), 0 —多返回函数不是最后一个,则只返回第一个返回值 print(a, b, c) —输出:1 0
print(back(), 0) —输出:1 0 print(0, back()) —输出:0 1 2
- 还可以return返回值
- 因为Lua在return时,就会让函数出栈,所以不会发生栈溢出的情况
<a name="M12oU"></a>
# 尾调用
- Lua中有尾调用消除的特性。
- 尾调用:当**函数1最后**一个动作是**调用函数2**而**不进行其他工作**,就会形成尾调用。
- 尾调用后,**程序不需要再次调用栈中储存的信息**,这样尾调用就**不会使用**任何**额外的栈空间**,就**不会发生堆栈溢出**
- 注:正确的尾调用,应该在**函数**最后**调用别的函数时**,**只需调用操作**,让**调用之后不要再回**到该**原函数中运行**。
```lua
function g(n)
if (n > 0) then
return g(n - 1)
end
end
--[[
该函数不会发生栈溢出,是正确的尾调用,,因为在运行return g(x-1)时,
不需要保存运行g(n)的数据到栈中,这时,栈就可以释放之前的空间,
因此就选运行无数次,都不会让栈发生溢出
--]]
function f(n)
if (n > 0) then
return f(n - 1)+1
end
end
--[[
该函数会发生栈溢出,不是正确的尾调用,因为在运行return f(n-1)+1时,
在内存中,因为f(n-1)函数运行完之后,还需要回到f(n)函数中进行+1操作,
因此,此时的f(n)不能再栈中被释放,
因此在多重嵌套的情况下,可能发生栈内存溢出的情况
--]]
函数是第一类值
第一类值:Lua语言中,函数和其他类型的值(字符串,数字)的权限相同,可以将某个函数保存到变量或表中
function foo(x) return 2*x end 相当于 foo=function(x) return 2*x end
在函数中可以嵌套函数(及使用高阶函数)
- 如:table.sort()函数,可以选择使用第二个为function的参数 ```lua sort = function(a, b) return a.name > b.name end
t = { {name = “abc”}, {name = “gfs”}, {name = “zxc”}, {name = “tacx”} } table.sort(t, sort) —table.sort()函数中,可以嵌套一个类型为function的变量来设定排序方式
function calculate(f, delta)
delta = delta or 1e-4
return function(x)
return (f(x + delta) - f(x)) / delta
end
— body
end
c=calculate(math.sin)
—[[
c代表储存着calculate函数的变量,并且设定其函数为math.sin后
c代表
function(x)
return (math.sin(x+delta)-math(x))/delta
end
该高阶函数的意义是,调用时设定函数f,求该函数的导数
—]]
print(c(5.2)) —相当于求math.sin(5.2)的导数
<a name="V3Lw6"></a>
# 局部函数
- 储存在局部变量中的函数
- **注:局部函数速度同样更快,但是表中的局部函数速度慢与全局函数**
<a name="jzza6"></a>
### 储存在表字段中
- 声明方式如下
```lua
--使用函数声明
Lib = {}
Lib.add = function(x, y)
return x + y
end
Lib.sub = function(x, y)
return x - y
end
print(Lib.add(3, 2), Lib.sub(3, 2)) --输出:5 1
--使用表构造器
Lib = {
add = function(x, y)
return x + y
end,
sub = function(x, y)
return x - y
end
}
--[[
在表构造器内,不能是愚弄function functionName() end的方式来构造局部函数
Lib={
function add(x,y)
return x+y
end
}
--]]
--特殊构造语法
Lib = {}
function Lib.add(x, y)
return x + y
end
function Lib.sub(x, y)
return x - y
end
局部函数声明
- local function f(params)
body
end
相当于
local f;
f=function(params)
body
end
- 声明时候不使用“向前”声明可能出现错误 ```lua
local fact=function (n) if n==0 then return 1 else return nfact(n-1) end end —该代码会出现错误,因为在调用return nfact(n-1)时,fact还没被声明为局部变量, —所以会找不到该变量,修改为 local fact fact = function(n) if n == 0 then return 1 else return n * fact(n - 1) end end ```