LUA Basics-Basic syntax

Source: Internet
Author: User
Tags anonymous closure constant error code error handling lua
type

Lua is a dynamic type language, that is, variable types can change.

You can test the type of a given variable by type, here's an example:

Print (Type ("HelloWorld"))	<span style= "White-space:pre" >	</span>-->string
print (type (1))				-->number
Print (type (nil))			-->nil
print (Type (true))			-->boolean
print (type)			-->function
Print (type ({x = 0, y = 1})	<span style= "White-space:pre" >	</span>-- >table
CO = coroutine.create (function ()
	print ("HelloWorld")
end)
print (Type (CO))				-- >thread	
The 7 basic types of LUA are shown above:

String number nil Boolean function table thread.

There is also a type of userdata, not yet know how to show ...

A few notes:

1. The nil type has only nil such a value.

2. Boolean has two values of true and false. In addition, all values in Lua can be used in conditional statements, except that false and nil are false, and others are true . Like 0, it means true.

3. Numeric type only number, no type int, float, etc.

4. String can be in double quotation marks or in single quotation marks. You can also use [ [ inside is a string ]], [[]] features can contain multiple lines, can be nested, and does not interpret the transfer character.

5. Function, like other types above, belongs to the first class of values, meaning that there can also be normal variables inside.

6. Table, UserData, and thread are also spoken later.


variables

Variables do not need to be declared.

A global variable is generated after assigning a value to a variable.

Print (a)	-->nil
a = 0
print (a)	-->0
a = "Hello World"
print (a)	-->hello world
A = nil---		Remove the variable a

A global variable that is not initialized can also be accessed, resulting in nil. The actual meaning is that if a variable is not nil, it means that the variable exists. So if you assign a variable to nil, it means that the variable is deleted.

Local variables can be created using the local keyword.

Do
local a
end
print (a)-	print nil because the life cycle of A has ended

Local variables are only valid within the code block that is declared. A code block can be a control structure, a function body, or a chunk (the file or string to which the variable is declared).

You can use multivariable assignments in Lua:

A,b,c = 1, "HelloWorld"
print (a)	-->1
print (b)	-->helloworld
Print (c)	-->nil

Multi-variable assignment is not very specific, = the right side if less than the left, then the corresponding variable is nil, such as the c;= right here if less than the left, then the extra assignment will be ignored.

Multi-variable assignment is also useful when a function returns because a function in Lua can return multiple values.
An expression

Some of the special points:

1. ~= is equivalent to the! = in C language, not equal to.

2. Table, UserData, and function are reference comparisons, and only two of the variables are equal to the same object.

3. The logical operator is "and or not", but here the and and or meanings are different from the C language:

A and B: If A is false, returns a, otherwise returns B;

A or B: If A is true, A is returned, or B is returned.

4. ".." Two points, which represent the character connector, and if the operand is number, is converted to a string:

Print (1.. 2)	-->12

Note here 1.. There is a space between, otherwise it will be an error.

However, if it is a string, you do not need:

Print ("Hello": " World ")	-->helloworld


structure of the table

Here is a basic example:

table1 = {}
--empty table names = {"Jack", "John", "Jimmy"}--the	list is initialized with
print (names[1])	<span style= "White-space:pre" >	</span>-->jack, subscript starting from 1
names[4] = "Jason"
print (names[4])	<span style= "White-space:pre" >	</span>-->jason
Print (names[5])	<span style= " White-space:pre ">	</span>-->nil, because there is
a = {x = 0, y = 1}	-->record form to initialize
print (a.x)		-->0
Print (a["x"])	<span style= "White-space:pre" >	</span>-->0, another way to express
B = {"HelloWorld", x = 1, "Goodbye"}--	mixed form
print (b[1])		-->helloworld
print (b.x)		-->1
Print (b[2])		-->goodbye
---print (b.1)---No such

A comma can be used for separating tables, or you can use semicolons.

There is a more general form:

A = {["+"] = "add", ["-"] = "Sub", ["*"] = "Mul", ["/"] = "div",}
Print (a["+"])	<span style= "White-space:pre" & gt;	</span>-->add
B = {[1] = "One", [2] = "One", [3] = "Three"}
print (b[1])		-->one

Control Statements

If statement:

If xxx then XXX end;

If xxx then xxx else xxx end;

If xxx then xxx elseif xxx then xxx else xxx end; ElseIf can have many, note that there are no spaces between else and if:

While statement:

While XXX does XXX end;

Repeat-until statement:

repeat xxx until xxx;

For statement:

For var=exp1,exp2,exp3 do xxx end; The statement in for here means that Var takes exp3 as step, from Exp1 to EXP2.

Several points to note:

1. Several exp will only run once, and before the For loop;

2. var is a local variable;

3. Do not change Var during the cycle.

For x, y, z in xxx do xxx end;

Break and Return statements:

Break exits the current loop; return exits the function and returns the result.

Note that break and return can only be used at the end of a block. If sometimes you really want to use in another place, you can use this way: do Break/return end;


function

Definition of the function:

function FuncName (args)
    states;
End
When it comes to function calls, if there are no parameters, you need to use ();

If the argument is a string or a table construct, you can use No ().

The matching of parameters and parameters in Lua functions is less than that, the arguments are more than formal parameters, the redundant ones are ignored, the parameters are less than the formal parameters, and the fewer form participants are nil. This is consistent with the variable assignment method.

Functions can return multiple values:

function func (void)
	return to
end;

b = func ()
print (a)	-->1
print (b)	-->2

Through () can be a function to force the return of a value:

function func (void)
	return to
end;

A, B = func ()
print (func ())	-->1 2
print ((func ()	))-->1
Lua can have mutable parameters. Use... Three points indicate that a table in the function named Arg is used to represent the parameter, and there is a field N in arg that represents the number of arguments.

Here is an example:

function func (...)
	--local arg = {...}
	For i,v in Ipairs ({...}) do
		print (i,v)
	end
end;
Func (0,1,2,3)
The result of the printing is:

1 0

2 1

3 2

4 3

A function parameter can be passed as a table, so there is no need to remember too many parameters, as in the following example:

--You do not need to create a special function func (new, old) function
func (args)
	print (args.new,args.old)
end
var = {new = 1, Old = 2}
func (Var)

The function is actually a variable, so there can be another way of expressing it, such as the following two ways:

function foo (x) return 2 * x end
Foo = function (x) return 2 * x end

They are actually the same. The second Foo is called the first class value function, and applying it to a table is the key to Lua's object-oriented and package mechanisms.

A function can also contain a function, which can access variables (including parameters) in the function that contains it, and the following is an example:

--Define a function that returns function
Newcounter ()
	Local i = 0
	return function ()
		i = i + 1
		return i
	end
  end
C1 = newcounter ()	-->C1 is the function returned, it is important to note that it captures the I variable
print (Newcounter ()
) in C1 ()-->1 Print (C1 ())	-->2
c2 = newcounter ()
print (C2 ())	-->1-->c2	is a new return function that captures the original I, So the print is 1.

The intrinsic function here and the (captured) variables it can access together constitute a concept called "Closure (closure)".

A typical closure consists of two parts, one is the closure itself, the other is the factory (the function that creates the closure).

A function in Lua is a variable, so it can be a global variable, the latter local variable. As an example of a local variable, such as a field in a table (like Io.read, read is a local function):

Lib = {}--	define a table
Lib.add = function (x, y) return x + y end-	-Create two local variables
lib.sub = function (x, y) ret Urn x-y end

print (lib.add)	-->2
Print (lib.sub)	-->0
The local functions in the table can also be represented in two ways:

The second type:

Lib = {
	add = function (x, y) return x + y end,--	delimiter Don't forget
	sub = function (x, y) return y x end
}
  
   --> define a table
print (lib.add)	-->2
print (Lib.sub ())	-->0
  
The third type:

Lib = {}
function Lib.add (x, y) return x + Y end
function lib.sub (x, y) return-X-y End

In addition, the local function is obtained by declaring Local in front of the function:

Do
local foo = function (x)
	print (x)
end
local function goo (x)
	print (x)
End

Foo (1 )
Goo (2)
end
-->foo (1)	error, access to the
-->goo (2)	error, access to the
When declaring a local function, you need to be aware of the recursive situation:

Local func---- 	
because there are two places to declare, if only in the first position, that is, the function is declared in front of the local,-
-and the subsequent func (x-1) position will not recognize it is local, so to find the global,
--Results will be error if not found, so here to do forward declaration


func = function (x)
	if x = = 0 Then
		return 1
	Else
		return x * func (X- 1)
	end
End
Print (func (3))
In addition, the functions in Lua support the "correct tail call", which looks like this:

function f (x)
  return g (x)
End
The call to G here is the tail call, in which case the G return does not need to be returned to the caller F, so there is no need to keep any information about the caller F in the stack. The correct tail call is that LUA does not use extra information when the tail is called, which is equivalent to a goto to another function.

The correct tail call makes recursion infinitely possible without causing the stack to overflow, and of course not only in recursion, but also in calls between multiple functions without worrying about stack overflow.

But note the form of the tail call, like These are not tail calls :

function f ()
  g ()
  return 
end
return g (x) + 1
return x or G (x)
return (g (x))


iterators and generics for

An iterator in Lua uses a common function to describe an iterator that returns the next element of the collection each time it is called.

Here is an example:

function Iterfactory (t)--	Create an iterator factory
	local i = 0
	local n = #t to get the length of the	table, only valid return for list form
	function ()--	This is the iterator
		i = i + 1
		if I <= n then
			return t[i]
		end
	end
End

aTable = { "One", "one", "three"}
f = iterfactory (aTable)
print (f ())	-->one
print (f ())	-->two Print
(f ())	-->three print
(f ())--	No printing
The above example is actually not much different from the closure example in the chapter "function". This is mainly about the following scenario that is used with the generic for:

function Iterfactory (t)--	Create an iterator factory
	local i = 0
	local n = #t to get the length of the	table, only valid
	for list form return function ()--	This is the iterator
		i = i + 1
		if I <= n then
			return t[i]
		end
	End
end< C34/>atable = {"One", "one", "three"} for
element in Iterfactory (aTable) do
	print (element)
end
The format of the generic for IS as follows:

For <var-list> on <exp-list> do
  <body>
end
Where Var-list's first variable is called a control variable, and if it is nil, the loop terminates; Exp-list is usually a call to an iterative factory, just like the previous iterfactory (aTable).

The following procedure is performed for a generic for loop:

1. Calculate the value of the expression in the back, which returns three values, namely the iteration function, the state constant, and the control variable, supplemented with nil if the return is not enough.

2. Call the iteration function as a parameter for the state constant and the control variable. (For A For loop, the state constant is not used, just get its value at initialization and pass it to the iteration function)

3. Assign the value returned by the iteration function to the list of variables.

4. If the first value returned is nil, the loop ends, otherwise the loop body is executed;

5. Go back to the second step and call the iteration function again.

So, the above generic for can be interpreted as the following pseudo-code:

Do
	local _f, _s, _var = Exp-list and
	true do
		local var_1, ..., var_n = _f (_s, _var)
		_var = var_1
		If _var = Nil then
			break
		end
		<block>
	end
End


Compile/Run/debug
first introduce the concept of chunk:

Chunk is a series of code. Each line of code that LUA executes, such as a file or interactive mode (which runs LUA without parameters at the command line, enters interactive mode) is a chunk.

A chunk can be a statement (for example, a line in interactive mode, a single line within a Do end), which can be a series of statements (such as the inside of a do end, or inside a for loop), or a function.

Here are a few functions:

dofile (): Used to connect an external chunk, which loads the file and executes it. Here is an example:

Dofile ("Iterator.lua")
The "Iterator.lua" here is the file where the previous chapter example is placed, and the code can be run by Dofile ().

Dofile is a primitive operation of Lua running code, it's just a helper, and the LoadFile () function is what really completes the function.

loadfile (): It compiles the code into an intermediate code and returns the compiled chunk as a function, but does not execute the code.

Note that the Lua language also compiles this action, although it is called a scripting language, but the LUA compiler is part of the language runtime, so it is very fast to compile and generate the intermediate code.

In addition, LoadFile () does not throw an error message but returns the error code, and LoadFile () returns nil and error messages when an error occurs.

Very similar to loadfile () there is a loadstring ():

loadstring (): reads the code from a string and compiles it into a function.

f = LoadString ("i = 1; Print (i) ")
F ()--	Here is the execution, just before the function is generated
or Jane writes:

LoadString ("i = 1; Print (i) ") ()--	pay attention to the following parentheses

LoadString () and LoadFile () will not throw an error, but will return nil and error messages, here is an example:

Print (LoadString ("I I"))
It prints the following error message:


It is important to note that loadstring () always compiles strings in the global environment, so it only recognizes global variables and does not see local variables:

Local i = 0
loadstring ("Print (i)") ()	-->nil

and a function similar to Dofile () is require ():

Require (): it is used to load the runtime library. The main difference from Dofile is the following points:

1. require () will search for directory load files.

2. require () will determine if the file has been loaded to avoid repeatedly loading the same file.

About the first difference: require () The path of the search takes the form of a list of patterns, such as the following:

?;?. Lua;/usr/local/lua/?/?. Lua

In the actual operation, such as require ("HelloWorld"), the parameter replaces the pattern, and searches for the replaced file: helloworld;helloworld.lua;/usr/local/lua/helloworld/ Helloworld.lua

Here is an example:


It actually runs the Helloworld.lua file. Note that the path here is stored in the global variable Lua_path, but it does not necessarily exist, and if it does not exist, use the default "?;?. Lua ".

About the second difference: there is a table in Lua that records all the files that have been loaded, but it is important to note that the name of the file is stored in the table. So if you use require ("HelloWorld") and require ("Helloworld.lua"), you will actually load the Helloworld.lua file two times instead of once.

Error (): end the program and return an error message. Here is an example:


assert (): accepts two parameters, and if the first argument is not true, the error is called (the information represented by the second argument).

Pcall (): encapsulates a possible error code (the error code is placed in a function, or is packaged as an anonymous function) for error handling. If there is no error, return true and call the function's return value, otherwise return false plus error information.

Here is an example:

--Possible error code encapsulated inside function
func () error 
	()--	throw error
end
-->pcall Call function
if Pcall (func Then 
	print ("no error")
else
	print ("error")
end
The above code prints the error.

Not only is the error message, when an error occurs, all parameters passed to the error () are returned by Pcall ():

--Possible error code encapsulated within function
func () 
	error ({code = 404})--	throws error
end
-->pcall Call function
local status, Err = Pcall (func)
if status = = False Then 
	print (err.code)
end
Printing results: 404.

co-process Coroutine

The co-process is similar to a thread, except that multiple threads can run at the same time, but only one of the processes is running.

The process is done through collaboration, and Lua is the resume () and yeild ().

The code that the process needs to run is encapsulated in a function that creates a process by passing the function name to the Create () function as a parameter, or, of course, passing the anonymous function directly as a parameter.

Here is an example:

CO = coroutine.create (
		function ()
			print ("HelloWorld")
		end
	)
print (CO)	-->thread : 0xXXXX (a 16-bit address)
The process has three states: Suspend state, run state, stop state.

When the process is created, it is in a suspended state. This means that the co-process does not run automatically.

To view the status by the co-process status ():

CO = coroutine.create (
		function ()
			print ("HelloWorld")
		end
	)
print (Coroutine.status (CO))	-->suspended

The resume () allows the process to enter a running state, after which the code ends up in a stop state:

CO = coroutine.create (
		function ()
			print (Coroutine.status (CO))
		end
	)
Coroutine.resume (CO)	-->running
Print (Coroutine.status (CO))	-->dead

The process can be suspended by yield ():

CO = coroutine.create (
	function ()
		for i=1,10 do
			print ("Co", I)
			Coroutine.yield ()
		End
	End
	)
Coroutine.resume (CO)
print (Coroutine.status (CO))	-->suspended	
The results of the operation are as follows:

If you run Resume () later:

Coroutine.resume (CO)
Coroutine.resume (CO)
Coroutine.resume (CO)
Coroutine.resume (CO)
The results of the operation are as follows:

When the number of calls exceeds 10 times:

Print (Coroutine.resume (CO))
The results of the operation are as follows:

The parameters can be passed between resume () and yield (), as shown in the following example:

Example one, the parameters of the resume () are passed to the co-process:

CO = coroutine.create (
	function (A, B, c)
		print ("Co", A, B, c)
	end
	)
Coroutine.resume (CO, 1, 2, 3) 
  -->resume are passed to the co-process.

For example two, the yield () parameter is also passed to resume ():

CO = coroutine.create (
	function (A, B)
		Coroutine.yield (A + B,-a)
	end
	)
print ( Coroutine.resume (Co, 20, 10))

In the run result, true indicates that the resume () runs successfully, and the subsequent 30 and 10 are the yield parameters.

For example three, the return value of the co-process code is also passed to resume ():

CO = coroutine.create (
	function (A, B)
		return a + B, a-c
	end
	)
print (Coroutine.resume (Co, 20, 10))

The result is the same as before.

The process is non-preemptive, so if a thread is blocked, the entire program stops. (Of course, there is a way to solve this, but in the basic part does not speak)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.