0x05 function
Definition and calling form
Definition : A function is an abstraction of statements and expressions .
The calling form of the function : whether it is a statement or an expression, all parameters need to be placed in a pair of parentheses. An empty pair of parentheses must be written even if the call has no arguments.
Note: There is one exception to this rule - a function has only one parameter, and that parameter is a literal string or table construct (see code below)
print "Hello World" --只有一个参数且为字面字符串
f{x = 20, y = 30} --只有一个参数且为table构造式
The colon operator Lua provides a special syntax for object-oriented calls - colon expressions such as
o.foo(o,x)
ando:foo(x)
are equivalent
Regarding the number of parameters in a function : The actual number of parameters provided by the calling function can be different from the number of formal parameters
function f(a, b) return a or b end
--调用函数 形参
f(3) a=3 b=nil
f(3,4) a=3 b=4
f(3,4,5) a=3 b=4 5被抛弃
The calling rules of functions in Lua are similar to the rules of multiple assignment
Parameter rule "If there are more actual parameters than formal parameters, the redundant actual parameters are discarded; if the actual parameters are less than the formal parameters, the redundant formal parameters are initialized to nil"
Multiple return values
Lua allows functions to return multiple results
function morevals()
return "Hello", "World"
end
print(morevals()) --"Hello" "World"
Multiple values can be returned directly in the function
Lua will adjust the return parameters according to the actual situation:
If you have the following function:
function foo0() end
function foo1() return "a" end
function foo2() return "a","b" end
- If a function call is the last expression, then Lua preserves as many return values as possible
x,y = foo2() x="a" y="b"
x,y,z = 10,foo2() x=10 y="a" z="b"
- If a function doesn't return a value or doesn't return enough values, Lua replaces the missing value with nil
x,y = foo0() x=nil y=nil
x,y = foo1() x="a" y=nil
- Returns only one value if a function is not the last element of a series of expressions
x,y = foo2(),20 x="a" y=20
x,y = foo0(),20,30 x=nil y=20 30被抛弃
A series of expressions : multiple assignments, argument lists passed in when a function is called, table constructors and return statements
- When a function is called as the last parameter of another function call, all return values of the first function will be passed to the second function as arguments
print (foo0())
print (foo1()) a
print (foo2()) a b
print (foo2(),10) a 10 (出现在表达式中时,Lua会将其返回值数量调整为1)
The table constructor can fully accept all returned parameters without any parameter adjustment
t = {foo0()} t={} (nil)
t = {foo1()} t={"a"}
t = {foo2()} t={"a","b"}
However, this only happens when the function is called as the last parameter, if it is elsewhere it will only return a value
- return statement:
return f()
will returnf()
all return values in
variable length parameter
Functions in Lua can receive different numbers of arguments, see the following code
function add(...)
local s = 0
for i,v in ipairs{...} do
s = s + v
end
return s
end
print(add(1,2,3,4)) -->10
The representations in the parameter table ...
can receive different numbers of arguments. When this function is called, it means that all parameters will be collected into one block. It still needs to be used when used in a function, ...
but at this time it is used as an expression --> {...}
represents an array constructed with all parameters.
The expression ...
behaves like a function with multiple return values.
selector is used to manipulate variable-length parameters.
If#
, so select will return the total number of variable-length parameters. The following code demonstrates howselector
to
for i=1, select('#', ...) do
local arg = select(i, ...)
<循环体>
end
--Lua5.0的代码如下
function foo(a, b, ...)
local arg = {...};
arg.n = select("#", ...)
end
named arguments
Specify arguments by name
For example a function os.rename, used to change the file name
rename{old = "temp.lua", new = "temp1,lua"}
What it does: Named arguments are useful when a function has a large number of parameters, most of which are optional.
w = Window{ x=0, y=0, width=200, height=100, title="lua"}
Functions are first-class values, which means that functions can be stored in variables like other traditional types of values.
Functions also have lexical domain: meaning that a function can be nested within another function, and inner functions can access outer functions
For the function print(), it actually refers to a variable print that stores a function that can print strings. This variable can store other functions.
a = print
a("Hello World") --Hello World
print = math.sin --现在print变量存储了math.sin引用的函数
a(print(1.0)) --调用了正弦函数,打印出结果 0.8414709848079
A function can be treated as a type
function foo() return "a" end
等价于
foo = function () return "a" end
An expression
function(x) <body> end
can be treated as a functional constructor like the table constructor
function
The application of expressions, table.sort
accepting a table and sorting it, one of the order functions can be created directly using the function expression when needed
network = {
{name = "a", IP = "1.2.3.4"},
{name = "b", IP = "2.4.21.3"},
{name = "c", IP = "2.32.24.33"}
}
--接下来调用table.sort
tabel.sort(network, function(a, b) return(a.name > b.name) end)
closed function
If a function is written inside another function, the inner function can access the local variables in the outer function.
names = {"Peter", "Paul", "Mary"}
gradees = {Mary = 10, Paul = 7, Peter = 8}
table.sort(names, function(n1, n2)
return grades[n1] > grades[n2]
end)
The above code is grades
neither a global variable nor a local variable in this anonymous function, it is called a "non-local variable"
Take a look at the following code to illustrate the rationale for the existence of non-local variables:
function newCounter()
local i = 0
return function()
i = i + 1
end
end
c1 = newCounter()
print(c1()) --1
print(c1()) --2
c2 = newCounter()
print(c2()) --1
Lua treats the above situation as Closure
a Closure
representation of a function plus the non-local variables accessed by the function. Functions c1
c2
are different (closed functions) created by the same Closure
function, they have different non-local variables i
non-global function
table
combine functions with
test = {}
test.foo1 = function(a, b) return a+b end
test.foo2 = function(a, b) return a-b end
test = {
foo1 = function(a,b) return a+b end,
foo2 = function(a,b ) return a-b end
}
--此外 Lua还提供了另外一种方式
test = {}
function test.foo1(a, b)
return a + b
end
function test.foo2(a, b)
return a - b
end
As soon as you store a function in a local variable, you get a 局部函数
function that can only be used in a specific scope
Definition of local functions
local f = function(参数)
<函数体>
end
local function f(参数)
<函数体>
end
Local functions are often used in recursive functions:
local fact = function(n)
if(n==0) then return 1
else return fact(n-1) --Error
end
end
fact(n-1)
The local definition has not been completed at the time of use fact
, so the global fact
function is called at this time. You can first define a local variable to save the function:
local fact
fact = function(n)
if(n==0) then return 1
else return fact(n-1)
end
end
tail call
When a function call is the last action of another function, the call is a "tail call" The tail call does not consume any stack space (tail call elimination)
function f(x) return g(x) end
--由于有尾调用消除的特性,下列函数不管传入什么数字都不会造成栈溢出
function foo (n)
if n >0 then return foo(n-1) end
end
Judge whether it conforms to the principle of tail call elimination :
after a function calls another function, does it have nothing else to do?
Only return <func>(<args>)
this form of call is considered a tail call in Lua