首页 > 代码库 > Lua function 函数

Lua function 函数

Lua支持面向对象,操作符为冒号‘:’。o:foo(x) <==> o.foo(o, x).

Lua程序可以调用C语言或者Lua实现的函数。Lua基础库中的所有函数都是用C实现的。但这些细节对于lua程序员是透明的。调用一个用C实现的函数,和调用一个用Lua实现的函数,二者没有任何区别。

 

函数的参数跟局部变量一样,用传入的实参来初始化,多余的实参被丢弃,多余的形参初始化为nil。

count=0function incCount(n)    n=n or 1    count=count+nendincCount()print(count)incCount(5)print(count)

多返回值

不同于常规函数,Lua的函数可以返回多个返回值。一些Lua中预定义的函数可以返回多个返回值。例如string.find函数,在string中匹配一个sub-string,string.find返回sub-string的起始位置和结束位置。利用多赋值语句来获取函数的多个返回值。


s,e=string.find("hello Lua","Lua")
print(s,e)

7 9

function maximum(a)    local mi=1 --index    local m=a[mi]    for i,val in ipairs(a) do        if val>m then            mi=i;m=val        end    end    return m,miendprint(maximum({8,10,23,12,5}))

ua会根据实际情况来使函数的返回值个数适应调用处的期望。

1)如果一个函数调用作为一条语句,所有的返回值都被丢弃

2)如果一个函数调用作为一个表达式的一部分时,返回值只保留第一个

3)只有当一个函数调用是一系列表达式中的最后一个元素(或仅有一个元素)时,才能获取它的所有返回值。这里的

“一系列表达式”在lua中表现为4中情况:

多重赋值,函数调用时传入的实参列表,,table的构造式,return语句中,。

在多重赋值中,若一个函数调用是最后的(或仅有的)一个表达式,那么Lua会保留尽可能多的返回值,用于
匹配赋值变量。

1.

function foo0() end
function foo1() return "a" end
function foo2() return "a","b" end

x,y=foo2()
x=foo2() x="a",b被丢弃。
x,y,z=10,foo2()   ->x=10,y="a",z="b"

2.

如果一个函数调用不是一系列表达式的最后一个元素,那么将只产生一个值:

x,y=foo2(),"c"
print(x,y)  a,c

 

 当一个函数调用作为另一个函数调用的最后一个(或仅有的)实参时,第一个函数的所有返回值都将作为实参传入第二个函数
这样的例子已经见到很多了,如print。:

print(foo2()) --a b

print(foo2(),1) --a 1

 

3. table构造式可以完整接受一个函数调用的所有结果。

t={foo2()}
print(#t)

4.

最后一个情况是return语句,诸如return f()这样的语句,将返回f的所有返回值。

 

也可以将一个函数调用放入一对圆括号中,从而迫使它只返回以结果:

print((foo2())) --a

请主语return语句后面的内容是不需要圆括号的,如果写成
return (f(x))
将只返回一个值。

关于多重返回值还有介绍一个特殊函数--unpack,他接受一个数组作为参数,并从下标1开始返回该数组的所有元素

print(unpack{10,20,30})
a,b=unpack{10,20,30} --a=10,b=20

An important use for unpack is in a generic call mechanism泛型调用. A generic call mechanism allows you to call any function, with any arguments, dynamically. In ANSI C, for instance, there is no way to do that. You can declare a function that receives a variable number of arguments (with stdarg.h) and you can call a variable function, using pointers to functions. However, you cannot call a function with a variable number of arguments: Each call you write in C has a fixed number of arguments and each argument has a fixed type. In Lua, if you want to call a variable function f with variable arguments in an array a, you simply write

    f(unpack(a))

The call to unpack returns all values in a, which become the arguments to f. For instance, if we execute

    f = string.find    a = {"hello", "ll"}

then the call f(unpack(a)) returns 3 and 4, exactly the same as the static call string.find("hello", "ll").

Although the predefined unpack is written in C, we could write it also in Lua, using recursion: 使用递归实现unpack。

    function unpack (t, i)      i = i or 1      if t[i] ~= nil then        return t[i], unpack(t, i + 1)      end    end

The first time we call it, with a single argument, i gets 1. Then the function returns t[1] followed by all results from unpack(t, 2), which in turn returns t[2] followed by all results from unpack(t, 3), and so on, until the last non-nil element.

 

 

变参

Lua中的一些函数接受可变数量的参数,例如print函数。print函数是用C来实现的,但是我们也可以用Lua来实现变参函数。下面是一个示例:

function add(...)    local s=0    for i,v in ipairs{...} do        s=s+v    end    return sendprint(add(3,4,5))

参数中的3个点(...)表示该函数可接受不同数量的实参,调用时3个点代表了实参。

表达式"..."的行为类似于一个具有多重返回值的函数,他返回的是当前函数的所有变长参数:
local a,b=...

上例用第一个和第二个变长参数来初始化这两个局部变量,实际上,还可以通过变长参数来模拟Lua中的
普通的参数传递机制。

如:
function foo(a,b,c)
等价于
function foo(...)
local a,b,c=...
end
对于那些喜爱Perl参数传递机制的人来说,可能会倾向于第二种形式。
如有这样一个函数:
function id(...)
return ...
end

他只是简单的返回所有市场。这是一个“多值恒定式(multi-value identity)"函数。
下面的这个函数行为非常类似于直接调用foo,但在调用foo()前先调用print:
function foo(...)
print("calling foo:",...)
return foo(...)
end
这种技巧对于跟踪某个特定函数调用很有帮助。

 

具有参数named argu 

(lua函数调用特殊语法,当实参只有一个table时,可以省略圆括号)。

w = Window{ x=0, y=0, width=300, height=200,
title = "Lua", background="blue",
border = true
}

indow函数可以检查必须的参数,并且给可选参数赋予默认值等。假设_Window函数可以用来创建一个新窗口,但是它必须要全部的参数。那我们就可以重新定义一个Window函数如下:

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

 

主要参考:

programming in lua:http://www.lua.org/pil/5.2.html