<Lua程序设计(第二版)>书摘-4

资料摘自<Lua程序设计(第二版)>

函数
在Lua中,函数是一种对语句和表达式进行抽象的主要机制。
function add(a)
    local sum=0
    for i,v in ipairs(a) do
        sum = sum + v
    end
        return sum
end
一个函数定义具有一个名称(本例中的add)、一系列的参数(参数表)和一个函数体(即一系列的语句)。
"形式参数(parameter)"的使用方式与局部变量非常相似,它们由调用函数时的"实际参数(argument)"初始化的。调用函数时提供的实参可以与形参数量不同。Lua会自动调整实参的数量,以匹配参数表的要求。这项调整与多重赋值很相似,即"若实参多于形参,则舍弃多余的实参;若实参不足,则多余的形参初始化为nil"。如:
function f(a,b) return a or b end
调用        形参
f(3)        a = 3,b= nil
f(3,4)      a=2,b=4
f(3,4,5)    a=3,b=4(5被丢弃了)
多重返回值
Lua具有一项非常与众不同的特征,允许函数返回多个结果。Lua的几个预定义函数就是返回多个值的。例如,用于在字符串中定位一个模式的函数string.find。例如,用于在字符串中定位一个模式的函数string.find。该函数若在字符串中找到了指定的模式,将返回匹配的起始字符和结尾字符的索引。在此就需要使用多重赋值语句来接收函数的返回值。
s,e= string.find("hello Lua users","Lua")
print(s,e)  -->7 9
以Lua编写的函数同样可以返回多个结果,只需在return关键字后列出所有的返回值即可。如:写一个函数用于查找数组中的最大元素,并返回该元素的位置:
function maximum(a)
    local mi = 1    --最大值的索引
    local m=a[mi]   --最大值
    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
Lua会调整一个函数的返回值数量以适应不同的调用情况:
function foo0() end                 --无返回值
function foo1() return "a" end      --返回1个结果
function foo2() return "a","b" end  --返回2个结果
若一个函数是最后的(或仅有的)一个表达式,那么Lua会保留其尽可能多的返回值:
x,y = foo2()        --x="a",y="b"
x = foo2()          --x="a","b"被丢弃
x,y,z = 10,foo2()   --x=10,y="a",z="b"
如果一个函数没有返回值或者没有返回足够的返回值,那么Lua会用nil来补充缺失的值:
x,y = foo0()        --x=nil,y=nil
x,y = foo1()        --x="a",y=nil
x,y,z = foo2()      --x="a",y="b",z=nil
如果一个函数调用不是一系列表达式的最后一个元素,那么将只产生一个值:
x,y = foo2(),20     --x="a",y=20
x,y = foo0(),20,30  --x=nil,y=20,30被丢弃
当一个函数调用作为另一个函数调用的最后一个(或仅有的)实参时,第一个函数的所有返回值都将作为实参传入第二个函数:
print(foo0())       -->
print(foo1())       -->a
print(foo2())       -->a b
print(foo2(),1)     -->a 1
print(foo2().."x")  -->ax
也可以将一个函数调用放入一对圆括号中,从而迫使它只返回一个结果:
print((foo0())) -->nil
print((foo1())) -->a
print((foo2())) -->a
变长参数
下面函数返回了所有参数的总和:
function add(...)
    local s = 0
    for i,v in ipairs{...} do
        s = s + v
    end
    return s
end


print(add(3,4,10,25,12))    -->54
参数表中的3个点(...)表示该函数可接受不同数量的实参。当这个函数被调用时,它的所有参数都会被收集到一起。这部分收集起来的实参称为这个函数的"变长参数"。
function fwrite(fmt,...)
    return io.write(string.format(fmt,...))
end
注意在3个点前有一个固定参数fmt。具有变长参数的函数同样也拥有任意数量的固定参数,但固定参数必须放在变长参数之前。Lua会将前面的实参赋予固定参数,而将余下实参视为变长参数。如:
fwrite()            fmt=nil,没有变长参数
fwrite("a")         fmt="a",没有变长参数
fwrite("%d%d",4,5)  fmt="%d%d",变长参数=4和5
下面演示如何使用select来遍历一个函数的所有变长参数:
for i=1,select('#',...) do
    local arg = select(i,...)   --得到第i个参数
    <循环体>
end
selcet("#",...)会返回所有变长参数的总数,其中包括nil。
具名实参
Lua中的参数传递机制是具有"位置性"的,也就是说在调用一个函数时,实参是通过在参数表中的位置与形参匹配起来的。第一个实参的值与第一个形参相匹配,依此类推。
但有时候你可能会要求通过名称来指定实参,使用os.rename来修改文件名称,通常你会忘记第一个参数是表示新文件还是旧文件,因此希望这个函数能接受两个具有名称的实参,如:
--无效的演示代码
rename(old="temp.lua",new="temp1.lua")
Lua并不直接支持这种语法,但可以通过一种细微的改变来获得相同的效果。
arg={old="temp.lua",new="temp1.lua"}
function rename(arg)
    return os.rename(arg.old,arg.new)
end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值