First, Function:
Functions are called in Lua in the same way as the C language, such as print ("Hello World") and a = Add (x, y). The only difference is that if the function has only one parameter and the type of the parameter is a string constant or a constructor for the table, the parentheses can be omitted, such as print "Hello world" and f {x = y = 20}.
LUA also provides a special syntax-the colon operator-for an object-style invocation. Another form of expression O.foo (o,x) is O:foo (x). The colon operator causes O to be suppressed as the first parameter of the function when calling O.foo.
Functions in Lua are declared in the following ways:
Copy Code code as follows:
function Add (a)
Local sum = 0
For I, V-ipairs (a) do
sum = sum + V
End
return sum
End
In the above declaration, the function name (add), the argument list (a), and the function body are included. It is to be explained that the number of arguments and formal parameters in Lua can be inconsistent, and once this happens, LUA's processing rules equate to multiple assignments, that is, more arguments than formal parameters, and that the extra parts are ignored, and conversely, the default value for uninitialized formal parameters is nil.
1. Multiple return values:
LUA supports returning multiple result values. Such as:
Copy Code code as follows:
S,e = String.find ("Hello Lua users", "LUA")
Print ("The Begin Index is" ...). S.. ", the end index is" ... E.. ".");
--The Begin index is 7, the end index is 9.
The above code example only demonstrates how to get multiple return values for the LUA function, and the following example shows how to declare a LUA function that returns multiple values. Such as:
[Code]
function Maximum (a)
Local mi = 1
Local m = A[mi]
For I, Val in Ipairs (a) do
If Val > m then
Mi,m = I,val
End
End
Return M,mi
End
Print (maximum{8,10,23,12,5})
--23 3
LUA adjusts the number of return values for a function to accommodate different invocation situations. When a function call is taken as a separate statement, LUA discards all return values for the function. If you call a function as part of an expression, Lua retains only the first return value of the function. All return values can be obtained only when a function call is the last element in a series of expressions. Here are three sample functions first, such as:
Copy Code code as follows:
function Foo0 () end
function foo1 () return "a" end
function Foo2 () return "a" and "B" end
The last thing to describe is the unpack function in Lua, which takes the array as an argument and returns all the elements of the array starting with subscript 1. Such as:
Copy Code code as follows:
/> Lua
> Print (unpack{10,20,30})
10 20 30
> a,b = unpack{10,20,30}
> Print (A,B)
10 20
> string.find (unpack{"Hello", "ll"})--equivalent to String.find ("Hello", "ll")
In Lua, unpack functions are implemented in C language. For ease of understanding, here are the same effects that are implemented recursively in Lua, such as:
Copy Code code as follows:
Function Unpack (t,i)
i = I or 1
If T[i] Then
Return T[i], unpack (t,i + 1)
End
End
2. Variable length parameters:
Functions in Lua can accept a different number of arguments, and they are declared and used in the following ways:
Copy Code code as follows:
function Add (...)
Local s = 0
For I, V in ipairs{...} do
s = s + V
End
return s
End
Print (Add (3,4,5,6,7))
--The output result is: 25
Explain, in the function declaration (...) Indicates that the function can accept a different number of parameters. When this function is called, all parameters are pooled together, and when it is accessed in the function, 3 dots (...) are still required. But the difference is that at this point these 3 points are used as expressions, such as {...} Represents an array of all the variable parameters. In a function that contains variable-length parameters, the same can be fixed, but the fixed parameter must be declared before the variable length parameter, such as:
Copy Code code as follows:
function test (arg1,arg2,...)
...
End
The last thing you need to note about LUA's variable-length arguments is that because the variable-length parameter may contain nil values, there is a problem with getting the number of arguments in the same way as getting the number of table elements (#). If you want to always get the correct number of arguments, you can use the Select function provided by LUA, such as:
Copy Code code as follows:
For i = 1, select (' # ',...) do--here ' # ' values indicate that the select returns the number of arguments (including nil).
Local arg = SELECT (I, ...)--The I representation here gets the first argument, and 1 is the number one.
--do something
End
3. With the reference:
In a function call, LUA's parameter rules are the same as the C language, and do not really support a real parameter. But we can simulate it by table, for example:
Copy Code code as follows:
function Rename (old,new)
...
End
Here we can get the above rename function to receive only one parameter, the table type parameter, while the Table object will contain old and new two keys. Such as:
Copy Code code as follows:
function Rename (ARG)
Local old = Arg.old
Local new = Arg.new
...
End
This modification is somewhat similar to JavaBean, which merges multiple parameters into one JavaBean. However, when used, the LUA table has a natural advantage, that is, if the function has only one argument and is a string or table type, you can call the function without parentheses, such as:
Copy Code code as follows:
Rename {old = "oldfile.txt", new = "Newfile.txt"}
Second, in-depth functions:
In Lua, a function is as anonymous as all other values, that is, none of them have names. When used, the variables that hold the function are manipulated, such as:
Copy Code code as follows:
A = {p = print}
A.P ("Hello World")
b = Print
B ("Hello World")
When declaring a LUA function, you can directly give the so-called function name, such as:
Copy Code code as follows:
function foo (x) return 2 * x end
We can also use this simpler way to declare functions in Lua, such as the following:
Copy Code code as follows:
Foo = function (x) return 2 * x end
Therefore, we can interpret the function as a type value composed of statements, and assign that value to a variable. This allows us to treat the expression "function (x) <body> end" as a constructor for a function, just like the {} of the table. We refer to the result of this function stereotype as an "anonymous function". The following example shows the convenience of an anonymous function, which is somewhat similar to an anonymous class in Java, such as:
Copy Code code as follows:
Table.sort (Test_table,function (a,b) return (A.name > B.name) end)
1. Closure (closed function):
If you write a function within another function, the internal function can access the local variables in the external function, as shown in the following example:
Copy Code code as follows:
function Newcounter ()
Local i = 0
return function ()--anonymous function
i = i + 1
return I
End
End
C1 = Newcounter ()
Print ("The return value of the". C1 ())
Print ("The return value of second called is". C1 ())
--The output result is:
--the return value of the 1
--the return value of second call is 2
In the example above, we refer to the Newcounter () function as the closure function. The local variable i in the function body is called "non-local variable", unlike the ordinary local variable, the variable is accessed and manipulated by the anonymous function within the Newcounter function. And then again, after the function Newcounter returns, its value is still preserved and can be used for the next calculation. Take a look at the following call mode.
Copy Code code as follows:
function Newcounter ()
Local i = 0
return function ()--anonymous function
i = i + 1
return I
End
End
C1 = Newcounter ()
C2 = Newcounter ()
Print ("The return value of the-a-call with C1 is". C1 ())
Print ("The return value of the-a-call with C2 is". C2 ())
Print ("The return value of second called with C1 is".. C1 ())
--The output result is:
--the return value of the-a-C1 is 1
--the return value of the-a-C2 is 1
--the return value of second call to C1 is 2
As a result, Lua makes a separate "non-local variable" for different closures each time it assigns a value to a new closure variable. The following example gives a more generic usage based on closures:
Copy Code code as follows:
Todo
--Here you assign the original file open function to the "private variable" oldopen, which is not accessible outside the block.
Local Oldopen = Io.open
--Add an anonymous function to determine the legality of this file open operation.
Local ACCESS_OK = function (Filename,mode) < check access rights > End
--point the original Io.open function variable to the new function, and call the old function in the new function to complete the real open operation.
Io.open = function (Filename,mode)
If ACCESS_OK (Filename,mode) Then
Return Oldopen (Filename,mode)
Else
return nil, "Access denied"
End
End
End
The above example is somewhat similar to the decorator pattern in design mode.
2. Non-global functions:
As you can see from the previous section, functions in Lua can be assigned not only directly to global variables, but also to other types of variables, such as local variables and fields in a table. In fact, most of the table in the LUA library comes with functions, such as Io.read, Math.sin, and so on. This type of writing is similar to the structure in C + +. Such as:
Copy Code code as follows:
Lib = {}
Lib.add = function (x,y) return x + y end
Lib.sub = function (x,y) return x-y end
Or it is initialized directly in the constructor of the table, such as:
Copy Code code as follows:
Lib = {add = function (x,y) return x + y end,
Sub = function (x,y) return x-y end
}
In addition, LUA provides another syntax for defining such functions, such as:
Copy Code code as follows:
Lib = {}
function Lib.add (x,y) return x + y end
function Lib.sub (x,y) return x-y end
For the local functions in Lua, the semantics are also very simple to understand. Since Lua is all about the program block as the execution unit, local functions within the block are inaccessible outside the program block, such as:
Copy Code code as follows:
Todo
Local F = function (X,y) return x + y end
--do something with F.
F (4,5)
End
For this local function, LUA also provides another, more concise definition, such as:
Copy Code code as follows:
Local function f (x,y) return x + y end
The wording is equivalent to:
Copy Code code as follows:
Local F
f = function (X,y) return x + y end
3. The correct tail call:
The optimization of such a function call is supported in Lua, that is, "tail call elimination." We can consider this function invocation as a goto statement, such as:
Copy Code code as follows:
function f (x) return g (x) End
Since the G (X) function is the last statement of the F (X) function, after function g returns, the F () function will not have any instructions to be executed, so when function g () returns, it can be returned directly to the call point of the F () function. Thus, once the LUA interpreter discovers that the G () function is the tail call of the F () function, the call to G () will not generate a stack overhead that is caused by a function call. It should be emphasized here that the tail call function must be the last statement of its calling function, otherwise LUA will not be optimized. In fact, however, we are actually not really tail calls in a lot of seemingly tail-call scenarios, such as:
Copy Code code as follows:
function f (x) g (x) End-no explicit hint of return statement
function f (x) return g (x) + 1-an instruction that requires one plus one to be executed after the G () function returns.
function f (x) return x or G (x)-If the G () function returns multiple values, the operation forces the G () function to return only one value.
function f (x) return (g (x))--the reason above.
In Lua, only the "return <func> (<args>)" form is the standard tail call, and if the parameter (args) contains an expression, the execution of the expression is done before the function call, so it does not affect the function as the tail call function.