函数有两种用途:1、完成指定任务,这种情况下函数作为调用语句使用;2、计算并返回值,这种情况下函数作为赋值语句的表达式使用。

Lua函数使用规则:

1、如果函数参数列表为空,必须使用()表名函数调用。例外是当函数只有一个参数并且这个参数是字符串或者表构造时,()可有可无

如:f {x = 1,y = 2}等价于 f({x = 1, y = 2})

2、Lua提供了面向对象方式调用函数的语法:o:foo(x)与o.foo(o,x)是等价的;

3、Lua使用的函数,即可是Lua编写,亦可是其他语言编写。

4、Lua函数形参和实参的匹配赋值语句类似,多余部分被忽略,缺少部分用nil补足

Lua函数返回值:

1、Lua函数可以返回多个结果值,如string.find,其返回匹配串开始和结束的下标:如下:

s, e = string.find("hello Lua users", "Lua")
print(s, e) --> 7 9


2、Lua函数中,在return后列出要返回的值的列表,即可返回多值,如下:


function maximum (a)
local mi = 1 -- maximum index local m 
a[mi] -- maximum value 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}))  --> 23 3

3、Lua通过调整返回值的个数使用调用环境,当作为独立的语句调用函数时,所有返回值将被忽略。

1)当作为表达式调用函数时,有以下几种情况:

(1)当调用作为表达式最后一个参数或者仅有一个参数时,根据变量个数,函数尽可能多的返回多个值,不足补nil,超出社区


function foo0 () end
-- returns no results
function foo1 () return 'a' end -- returns 1 result
function foo2 () return 'a','b' end -- returns 2 results
x,y = foo2()
-- x='a', y='b'
x = foo2()

-- x='a', 'b' is discarded
x,y,z = 10,foo2() -- x=10, y='a', z='b'
x,y = foo0()  -- x=nil, y=nil
x,y = foo1()  
-- x='a', y=nil
x,y,z = foo2()
-- x='a', y='b', z=nil
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">(2)其他情况,函数调用金返回第一个值。</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span><p></p><pre name="code" class="plain">x,y = foo2(), 20 -- x='a', y=20

x,y = foo0(), 20, 30 -- x='nil', y=20, 30 is discarded



2)函数调用作为函数参数被同时调用时,和多值赋值相同


print(foo0()) -->
print(foo1()) --> a
print(foo2()) --> ab
print(foo2(), 1)  --> a1
print(foo2() .. "x")  --> ax

3)函数调用在表构造函数中,初始化时,和多赋值时相同

a = {foo0(), foo2(), 4} -- a[1] = nil, a[2] = 'a', a[3] = 4
a = {foo2()}  -- a = {'a', 'b'}

另外:return   f()这种形式,则返回f()的返回值,return使用圆括号将返回值括起来,也将导致返回一个值。但是可以通过unpack函数,来返回函数的所有返回值。如:f = string.find      a={“Hello”,“ll”}    print(f(unpack(a)))   -- 3   4

可变参数:

Lua函数可以接受可变数目的参数,和C语言类似,使用…表示参数是可变的,Lua将函数的参数放在一个叫arg的表中,除了参数以外,arg表中还有一个域n表示参数的个数。如:Lua会将前面的实参传递给函数的固定参数,后面的实参放在arg表中

function   g(a,b,  ...)   end

CALL                  arg表
g(3)                   a=3,b=nil,arg={n=0}
g(3,4)                a=3,b=4,arg={n=0}
g(3,4,5,6)             a=3,b=4,arg={5,6,n=2}

此处就不详细介绍可变参数,更多内容可参考Lua中文教程28页内容

命名参数:Lua的函数参数是和位置相关的,调用实参会按顺序依次传递给形参。所有,用名字指定参数是很有用的。

如:rename(old = "temp.lua",  new = "tempNew.lua")代码是无效的,Lua可以通过将所有的参数放在一个表中,把表作为函数的唯一参数来实现传参。

如:rename {old = "temp.lua", new = "tempNew.lua")

Lua函数中得第一类值:在Lua中函数和其他值一样,函数可以被存放在变量中,也可以存放在表中,可以作为函数的形参,也可以作为函数的返回值。

词法定界:嵌套的函数可以访问它外部函数中的变量。当一个函数内部嵌套另一个函数定义时,内部的函数可以访问外部的函数的局部变量,这种特征乘坐词法定界。

闭包: