lua函数

来源:互联网 发布:淘宝售假次数清零吗 编辑:程序博客网 时间:2024/06/06 20:15

1:lua函数是匿名的

lua函数和其它lua值一样,都是匿名的,即它们本身没有名称。当讨论一个函数(如print)时,实际上是讨论一个持有某函数的变量。这于一个变量持有其它lua值是一个道理。如

function foo(x) return 2*x end  与 foo=function(x) return 2*x end 是等价关系。

再如:table.sort函数参数第二个参数就需要一个匿名函数参数

network = {
{name = "grauna",IP="210.26.30.34"},
{name="arraial",IP="210.26.30.23"},
{name ="lua",IP="210.26.23.12"},
{name = "derain",IP="210.26.23.20"},
}
table.sort(network,function(a,b) return (a.name>b.name) end)

像table.sort这类接收一个匿名函数作为实参的函数属于高阶函数。

正是lua函数是匿名的原因,当讨论一个函数(如print)时,实际上是讨论一个持有某函数的变量。所以lua函数可以存储在全局变量或者局部变量中。

比如table.sort函数就是一个局部函数。再如package模块里的某些函数,也只是在该package里可见。


2:形参的使用与C函数的形参使用有点区别;在lua中可以修改形参的值,如下

function func(n)

n = n or 1

count = count + n

end


3:lua函数支持多重返回值,lua程序设计第二版53页有一句话:只有当一个函数调用是一系列表达式中的最后一个元素(或仅有一个元素)时,才能获得它的所有返回值。另外一种情况是:可以使用圆括号强制使函数调用只返回一个值,一个return语句如果使用圆括号将函数调用括起来将导致返回一个值。


4:unpack函数

函数unpack,接受一个数组作为输入参数,返回数组的所有元素

f = string.find

a = {"hello""ll"}

print(f(unpack(a)))      --> 3  4


5:可变参数,变长参数(...),三个点表示该函数可以接收数量不定的参数。

function fwrite(fmt, ...)

return io.write(string.format(fmt, ...))

end

注意:在3个点前有一个固定参数fmt,  具有变长参数的函数同时可以拥有任意固定的参数。

fwrite("%d%d", 4,5)   fmt="%d%d", 4,5属于变长参数


6: lua函数select用于访问所有的变长参数,包括nil。调用select函数的的模式:

select( selector, ...)

调用select,必须传入一个固定的实参selector。

for i = 1, select('#' , ...)  do

local arg = select(i, ...)    --得到第i个参数

print(arg)

end

特别需要指出 select('#', ...)会返回所有变长参数的总数量,包括nil也计算在内。

function func(...)
    for i=1,select('#',...) do
        arg = select(i,...)
        print(i,arg)
    end 
end
func(1,2,5,"abcd",'agagsagasl')

输出结果:

[ly@localhost testLua]$ lua test-select.lua
1       1
2       2
3       5
4       abcd
5       agagsagasl


7:深入理解closure和非局部变量(non local variable)。closure的简单定义:一个closure就是一个函数加上该函数所需访问的所有“非局部的变量“。

names = {"Peter", "Paul", "Mary"}grades = {Mary = 10, Paul = 7, Peter = 8}
function sortbygrade (names, grades)    table.sort(names, function (n1, n2)        return grades[n1] > grades[n2]        -- 比较年级     end)end
传递给sort的匿名函数可以访问参数grades,而grades是外部函数sortbygrade的局部变量,注意函数sortbygrade的形参grades也属于该函数的局部变量。所以table.sort函数的第二个参数就属于一个closure。
再看以下例子:
function newCounter()    local i = 0    return function ()      -- 匿名函数        i = i + 1        return i    endendc1 = newCounter()print(c1())     --> 1print(c1())     --> 2
c2 = newCOunter()print(c2())    --> 1print(c1())    --> 3print(c2())    --> 2
c1和c2是同一个函数所创建的两个不同的closure,它们各自拥有局部变量i的独立实例。
8:lua函数尾调用
当一个函数调用是另一个函数的最后一个动作时,该调用才算是一条尾调用。比如以下代码对g函数的调用就属于尾调用:
function foo(x) return g(x) end
尾调用的特性是不耗费任何栈空间,所以一个程序可以拥有无数嵌套的尾调用。







1 0
原创粉丝点击