目录
码云代码链接
https://gitee.com/wenwenc9/lua_pro.git
Lua 提供了许多的内建函数
Lua 函数主要有两种用途:
1.完成指定的任务,这种情况下函数作为调用语句使用;
2.计算并返回值,这种情况下函数作为赋值语句的表达式使用。
Lua 编程语言函数定义格式如下:
optional_function_scope function function_name( argument1, argument2, argument3..., argumentn)
function_body
return result_params_comma_separated
end
解析:
-
optional_function_scope
: 该参数是可选的制定函数是全局函数还是局部函数?未设置该参数默认为全局函数,如果你需要设置函数为局部函数需要使用关键字 local。
fucntion 声明函数所用 -
function_name
:
指定函数名称。 -
argument1, argument2, argument3..., argumentn
:
函数参数,多个参数以逗号隔开,函数也可以不带参数。 -
function_body
:
函数体,函数中需要执行的代码语句块。 -
result_params_comma_separated
:
函数返回值,Lua语言函数可以返回多个值,每个值以逗号隔开。
一、例子
function max(num1,num2)
if (num1 > num2) then
result = num1;
else
result = num2;
end
return result
end
print('两个比较最大值为',max(10,4))
print('两个比较最大值为',max(5,6))
二、多返回值
string.find:返回匹配串"开始和结束的下标"(如果不存在匹配串返回nil)
s, e = string.find("www.abc12345.cn", "ab")
print(s, e) -- 5 13
设定最大值为8,如果v大于8则返回
function maximum(a)
local mi = 1 -- 最大值索引
local m = a[mi] -- 最大值 8
for i, val in ipairs(a) do
if val > m then
mi = i
m = val
end
end
return m, mi
end
print(maximum({ 8, 10, 23, 12, 5 }))
三、可变参数-万能参数
Lua函数可以接受可变数目的参数,和C语言类似在函数参数列表中使用三点(…) 表示函数有可变的参数,除了参数以外,arg
表中还有一个域 n 表示参数的个数
Lua将函数的参数放在一个叫arg
的表中,#arg
表示传入参数的个数。
例如,我们计算几个数的平均值:
function average(...)
result = 0
local arg={...}
for i,v in ipairs(arg) do -- 累计求和
result = result + v
end
print("总共传入 " .. #arg .. " 个数")
return result/#arg
end
print("平均值为",average(10,5,3,4,5,6))
总共传入 6 个数
平均值为 5.5
例如,我们可以重写 print 函数:
printResult = ""
function print(...)
for i,v in ipairs(arg) do
printResult = printResult .. tostring(v) .. "\t"
end
printResult = printResult .. "\n"
end
有时候我们可能需要几个固定参数加上可变参数
function g (a, b, ...) end
CALL PARAMETERS
g(3) a=3, b=nil, arg={n=0}
g(3, 4) a=3, b=4, arg={n=0}
g(3, 4, 5, 8) a=3, b=4, arg={5, 8; n=2}
如上面所示,Lua 会将前面的实参传给函数的固定参数,后面的实参放在 arg 表中。
举个具体的例子,如果我们只想要 string.find 返回的第二个值。一个典型的方法是
使用哑元(dummy variable,下划线):
local _, x = string.find(s, p)
-- now use `x'
...
还可以利用可变参数声明一个 select 函数:
function select (n, ...)
return arg[n]
end
print(string.find("hello hello", " hel")) --> 6 9
print(select(1, string.find("hello hello", " hel"))) --> 6
print(select(2, string.find("hello hello", " hel"))) --> 9
有时候需要将函数的可变参数传递给另外的函数调用,可以使用前面我们说过的
unpack(arg)返回 arg 表所有的可变参数,Lua 提供了一个文本格式化的函数 string.format
(类似 C 语言的 sprintf 函数):
function fwrite(fmt, ...)
return io.write(string.format(fmt, unpack(arg)))
end
这个例子将文本格式化操作和写操作组合为一个函数
四、命名参数
Lua 的函数参数是和位置相关的,调用时实参会按顺序依次传给形参。有时候用名
字指定参数是很有用的,比如 rename 函数用来给一个文件重命名,有时候我们我们记不
清命名前后两个参数的顺序了:
– invalid code
rename(old="temp.lua", new="temp1.lua")
上面这段代码是无效的,Lua 可以通过将所有的参数放在一个表中,把表作为函数
的唯一参数来实现上面这段伪代码的功能。因为 Lua 语法支持函数调用时实参可以是表
的构造。
rename{old="temp.lua", new="temp1.lua"}
根据这个想法我们重定义了 rename:
function rename (arg)
return os.rename(arg.old, arg.new)
end
当函数的参数很多的时候,这种函数参数的传递方式很方便的。例如 GUI 库中创建
窗体的函数有很多参数并且大部分参数是可选的,可以用下面这种方式:
w = Window {
x = 0, y = 0, width = 300, height = 200,
title = "Lua", background = "blue",
border = true
}
function Window (options)
-- check mandatory options
if type(options.title) ~= "string" then
error("no title")
elseif type(options.width) ~= "number" then
error("no width")
elseif type(options.height) ~= "number" then
error("no height")
end
-- everything else is optional
_Window(options.title,
options.x or 0,
-- default value
options.y or 0,
-- default value
options.width, options.height,
options.background or "white", -- default
options.border
-- default is false (nil)
)
end
五、闭包
案例 1
function test()
local i=0
return function() -- 匿名函数
i= i + 1
return i
end
end
c1=test()
c2=test()
print(c1()) -- 1
print(c1()) -- 2//重复调用时每一个调用都会记住上一次调用后的值,就是说i=1了已经
print(c2()) -- 1//闭包不同所以upvalue不同
print(c2()) -- 2
print(c2()) -- 3
闭包:
- 内部函数调用外部函数的变量
- 返回内部函数(可以是匿名函数放回)
- 外部函数+外部函数创建的upvalue+内部函数(闭包函数)
- 闭包是运行的时候形成的,运行的时候upvalue会
单独开辟一块内存来存放
function list_iter(t)
local i=0
local n=table.getn(t)
return function()
i=i+1
if i<=n then return t[i] end
end
end
案例 2
function DoActive()
local Hp = 100
local Mp = 100
function GetHp()
Hp= Hp + 1
return Hp
end
return GetHp()
end
--此时在方法体外去接受DoActive
local A = DoActive()
--此时DoActive会把跟GetHp()相关联的数据形成一个闭包return出来(Hp),而无用的数据(Mp)会被GC掉
--现在A中 有GetHp函数,并且Hp = 101 形成闭包的函数跟数据会在一个空间内储存并挂起,调用时执行
A() -- Hp = 102
A() -- Hp = 103
匿名返回
function DoActive()
local Hp = 100
local Mp = 100
function GetHp()
Hp= Hp + 1
return Hp
end
return GetHp
end
local A = DoActive()
A() -- Hp = 102
A() -- Hp = 103
案例 3
function Incremnet(n)
function show()
print(n)
end
function Add()
n = n +1
end
return show,Add
end
f1,f2 = Incremnet(10)
g1,g2 = Incremnet(20)
f1() -- show 10
f2() -- Add 10 + 1
f1() -- show 11
g1() -- show 20
g2() -- add 20 + 1
g1() -- show 21
六、非全局函数
local 声明
七、尾调用
一个函数调用另外一个函数(并且使用其值)就是尾调用