The functions in Lua are the same as those in C ++. The function Format in Lua is as follows:
| 123 |
function MyFunc(param) -- Do something end |
When calling a function, you also need to put the corresponding parameters in a pair of parentheses. Even if there are no parameters when calling the function, you must write a pair of empty parentheses. This rule has only one special exception: If a function has only one parameter and the parameter is a string or table constructor, parentheses can be omitted. See the following code:
| 123456 |
print "Hello World"--> print("Hello World") Equivalentprint [[a multi-line message]] -->print([[a multi-line --> Message]) equivalent-- F is a function.F {x = 10, y = 20} --> F ({x = 10, y = 20}) is equivalent |
Some of the above Code is easy to write. If you are not familiar with it, it will be confusing to read other people's code.
A function definition has a name, a series of parameters, and a function body. When a function is defined, the parameters are used in a very similar way to local variables. They are initialized by the "actual parameters" when a function is called. The number of real parameters provided when a function is called can be different from the number of parameters. Lua will automatically adjust the number of real parameters to match the requirements of the parameter table. If "real parameters are redundant, excess real parameters are discarded. If the real parameters are insufficient, the excess parameters are initialized as nil ". This is very similar to the multiple return values described below.
Multiple return values
This should be a feature of Lua. To allow a function to return multiple results, you only need to list all return values after the return keyword. The following is a description of the situation:
| 12345678910111213141516171819202122232425262728293031323334353637383940 |
Function foo0 () end -- no return valuefunction foo1() return "a" End -- returns a result.function foo2() return "a", "b" End -- two results are returned. -- When multiple values are assigned, if a function call is the last or only expression,-- Then Lua retains as many return values as possible to match the value variable.x, y = foo2() -- x = "a", y = "b"x = foo2() -- x = "a", "b"Discardedx, y, z = 10, foo2() -- x = 10, y = "a", z = "b" -- If a function does not return a value or does not have enough values, Lua will use-- Nil to add missing valuesx, y = foo0() -- x = nil, y = nil x, y = foo1() -- x = "a", y = nil x, y, z = foo2() -- x = "a", y = "b", z = nil -- If a function call is not the last element of a series of expressions, only one value is generated:x, y = foo2(), 20 -- x = "a", y = 20 X, Y = foo0 (), 20, 30 -- X = nil, y = 20, 30 is discarded -- The table constructor can completely receive all the results of a function call, that is, no quantity-- AdjustmentsLocal T = {foo0 ()} -- t = {} (an empty table)local t = {foo1()} -- t = {"a"} local t = {foo2()} -- t = {"a", "b"} -- However, the above behavior only happens when a function call acts as the last element,-- Function calls at other locations always generate only one result valuelocal t = {foo0(), foo2(), 4} -- t[1] = nil, t[2] = "a", t[3] = 4 -- We can also usereturnReturns another function.Function myfunc () -- returns return Foo1 () -- Note: here isreturn Foo1 () insteadreturn (foo1()) end -- return Foo1 () andreturn (Foo1 () is two completely different meanings-- Place a function call in a pair of parentheses to force it to return only one resultprint((foo0())) -- nil print((foo1())) -- a print((foo2())) -- a |
Variable Length Parameter
In C, the function can accept different numbers of real parameters, and the function in Lua can also accept different numbers of real parameters, such as the following code:
| 12345678 |
-- Print all parametersfunction VarArguments(...) for i, v in ipairs{...} do print(v) end end VarArguments(1, 2, 3) |
3 points in the parameter table (...) This function can accept different numbers of real parameters. When this function is called, all its parameters will be collected together. The collected real parameters are called the variable length parameters of the function ". When a function needs to access its variable length parameter, it still needs three points (...). However, the difference is that these three points are used as an expression. In the above example, the expression {...} An array composed of all variable length parameters. Pay attention to the use of variable length parameters in the C language.
Generally, when traversing a variable-length parameter, a function only needs to use the expression {...}, This is like accessing a table, accessing all variable-length parameters. However, in some special cases, the variable length parameter may contain some nil that is intentionally passed in. In this case, you need to use select to access the variable length parameter. When you call select, you must pass in a fixed Real parameter selector and a series of variable length parameters. If selector is the number N, select returns the nth variable real parameter; otherwise, selector can only be the string "#", so that select returns the total number of variable-length parameters, see the following code:
| 1234 |
for i = 1, select(‘#‘, ...) do Local Arg = select (I,...) -- Obtain the I-th parameter. -- Do something elseend |
Select ('#',...) Returns the total number of all variable-length parameters, including nil (remember table. maxn ?) For Lua 5.0, the variable length parameter has another mechanism. The syntax for declaring a function is the same, and the three points are used as the last parameter. But Lua 5.0 does not provide "..." Expression. Instead, an implicit local table variable "Arg" is used to accept all variable-length parameters. This table also has a field named "N" to record the total number of variable-length parameters. For example, the following code:
| 12345 |
function MyFunc(a, b, ...) print(arg.n) end MyFunc(1, 2, 3, 4, 5) -->3 |
The disadvantage of this old mechanism is that every time a program calls a function with variable length parameters, a new table is created. In the new mechanism, the table for Variable Length Parameter access is created only when necessary. This is just a brief introduction to this method. Don't read others' code !!!
In-depth discussion of functions
In Lua, functions have the same rights as other traditional types of values. Functions can be stored in variables or tables, passed to other functions as real parameters, and returned values of other functions. A confusing concept in Lua is that functions are anonymous like all other values, that is, they have no names. When discussing a function name, we are actually discussing a variable that holds a function, for example, the following code:
| 123456 |
-- We often define functions like thisfunction foo(x) return 2 * x end -- In fact, this is just a "syntactic Sugar;-- The above Code is only a simplified form of the following codefoo = function (x) return 2 * x end |
In fact, a function definition is actually a statement (more accurately a value assignment statement). This statement creates a value of the type "function, and assign this value to a variable. Because a function is a common value in Lua, it can be stored in not only global variables, but also local variables and even table fields.
Embedded Functions
If a function is written in another function, the internal function can access local variables in the external function. This feature is called "lexical domain ". Let's take a look at the following interesting code:
| 1234567891011 |
function newCounter() local i = 0 return Function () -- anonymous Function i = i + 1 return i end end c1 = newCounter() Print (C1 () --> what is output?Print (C1 () --> what is output? |
If you understand the output above and the code above, you do not need to read this section about closed functions. In the above Code, there is a variable I. For the newcounter function, I is a local variable, but for anonymous functions, when it accesses this I, I is neither a global variable, it is not a local variable. For us, we call this variable a "non-local variable ". The following code is the same:
| 12345678910 |
function newCounter(i) return Function () -- anonymous Function i = i + 1 return i end end c1 = newCounter(10) Print (C1 () --> what is output?Print (C1 () --> what is output? |
An anonymous function accesses "non-local variable" I, which is used to maintain a counter. At first glance, because the function that creates the variable I, that is, newcounter, has returned, I should be out of the scope of the function every time I call an anonymous function. However, Lua correctly handles this situation with closure. Here, a closure is all the "non-local variables" that a function needs to access ". If newcounter is called again, it will create a new local variable I to get a new closure. In the subsequent summary, I will specifically summarize a blog post about the closure in Lua, so stay tuned.
Non-global functions
Because functions are the same as common variables, they can be stored in not only global variables, but also table fields or local variables. We can store the function in a table, such as the following code:
| 123 |
Lib = {} Lib.foo = function (x, y) return x + y end Lib.goo = function (x, y) return x - y end |
If you store a function in a local variable, you get a "Local function". That is to say, this function can only be effective within a specific scope. We can define a local function as follows:
| 1234567 |
Local F = function (<parameter>) <Function body>end -- Lua also provides a special "syntactic sugar"Local function f (<parameter>) <Function body>end |
Sometimes, we need to make a pre-declaration of the function, such as the following code:
| 1234567891011 |
local f, g function f() <Other operations> g() end function g() <Other operations> f() end |
Summary
This blog post summarizes the functions in Lua. At least after reading this blog, you will use Lua to write the functions and use the functions in Lua. However, there is no summary of the deep things, such as the closure ". I will write a special article about closures in Lua.
Source: http://www.jellythink.com/archives/495