首页 > 代码库 > 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