
Lua由巴西里约热内卢天主教大学PUC-Rio的一个团队设计、实施和维护。”Lua”(发音为LOO-ah)在葡萄牙语中的意思是”月亮”。
Lua 是一种强大、高效、轻量级、可嵌入的脚本语言。它支持过程编程、面向对象编程、函数编程、数据驱动编程和数据描述。
Lua 将简单的过程语法和基于关联数组和可扩展语义的强大数据描述构造相结合。Lua 是动态键入的,通过使用基于寄存器的虚拟机解释字节码来运行,并且具有具有增量垃圾回收的自动内存管理,因此非常适合配置、脚本编写和快速原型设计。
安装
Lua官网下载:www.lua.org/download.html。
1 | tar zxvf lua-5.x.x.tar.gz |
2 | cd lua-5.x.x |
3 | make linux test |
4 | make install |
注释
变量
数据类型
| 数据类型 |
描述 |
| nil |
表示一个无效值,只有值nil属于该类,相当于条件表达式中的false |
| boolean |
true(0,空字符串是true)或者false(只有nil和false是false) |
| number |
双精度类型的实浮点数 |
| string |
‘’或””或[[]]表示 |
| function |
c或lua编写的函数 |
| userdata |
用来将任意c数据结构保存到lua变量中 |
| thread |
用来实现coroutine |
| table |
关联数组 |
Lua中的变量默认是全局变量,哪怕是语句块或函数里。除非用local显示声明为局部变量。
变量的默认值均为nil。
lua可以对多个变量同时赋值,赋值语句右边的值会依次赋给左边的变量。
1 |
|
2 |
|
3 |
|
4 |
|
5 | a, b, c = 0, 1 |
6 | a, b = a+1, b+1, b+2 |
7 | a, b, c = 0 |
8 | x, y = y, x |
流程控制
while
1 | sum = 0 |
2 | num = 1 |
3 | while num <= 100 do |
4 | sum = sum + num |
5 | num = num + 1 |
6 | end |
7 | print("sum = ",sum) |
for
1 | sum = 0 |
2 | for i=1, 100 do |
3 |
|
4 |
|
5 | sum = sum + i |
6 | end |
until
1 | sum = 2 |
2 | repeat |
3 | sum = sum ^ 2 |
4 | print(sum) |
5 | until sum > 1000 |
if-else
1 | a = 100 |
2 | if(a == 10) then |
3 | print("a == 10") |
4 | elseif a == 20 then |
5 | print("a == 20") |
6 | elseif(a == 30) then |
7 | print("a == 30") |
8 | else |
9 | print("a nothing") |
10 | end |
函数
递归
1 | function fib(n) |
2 | if n < 2 then |
3 | return 1 |
4 | end |
5 | return fib(n-2) + fib(n-1) |
6 | end |
闭包
1 | function newCounter() |
2 | local i = 0 |
3 | return function() |
4 | i = i + 1 |
5 | return i |
6 | end |
7 | end |
8 |
|
9 | ci = newCounter() |
10 | print(c1()) |
11 | print(c1()) |
多返回值
1 | function maximum(a) |
2 | local mi = 1 |
3 | local m = a[mi] |
4 | for i,val in ipairs(a) do |
5 | if val > m then |
6 | mi = i |
7 | m = val |
8 | end |
9 | end |
10 | return m, mi |
11 | end |
12 | print(maximum({8,10,23,12,3,9})) |
表table
1 | atable = {} |
2 |
|
3 | atable[1] = "lua" |
4 | atable = nil |
5 |
|
6 | arr = {"string", 100, "haoel", function() print("cooool") end} |
7 | for i = 1, #arr do |
8 |
|
9 |
|
10 | print(arr[i]) |
11 | end |
Lua提供了元表(metatable),允许我们改变table的行为(例如:两表相加),每个行为关联了对应的元方法。
- setmetatable(table,metatable):对指定table设置元表(metatable),如果元表中存在__metatable键值,setmetatable会失败。
- getmetatable(table): 返回对象的元素。
1 | atable = {} |
2 | ametatable = {} |
3 | setmetatable(atable, ametatable) |
4 |
|
5 | atable = setmetatable({},{}) |
6 | getmetatable(atable) |
| 模式 |
描述 |
| __add(a, b) |
a + b |
| __sub(a, b) |
a - b |
| __mul(a, b) |
a * b |
| __div(a, b) |
a / b |
| __mod(a, b) |
a % b |
| __pow(a, b) |
a ^ b |
| __unm(a) |
-a |
| __concat(a, b) |
a..b |
| __len(a) |
#a |
| __eq(a, b) |
a == b |
| __lt(a, b) |
a < b |
| __le(a, b) |
a <= b |
| __index(a, b) |
a.b |
| __newindex(a, b, c) |
a.b = v |
| __call(a,…) |
a(…) |
__index
1 | arrtable = setmetatable({key1 = "value1"},{ |
2 | __index = function(arrtable, key) |
3 | if key == "key2" then |
4 | return "cooooooool" |
5 | else |
6 | return nil |
7 | end |
8 | end |
9 | }) |
10 |
|
11 | arrtable = setmetatable({key1 = "value1"},{__index = {key2 = "metablevalue"}}) |
12 | print(arrtable.key1, arrtable.key2) |
如上所示,Lua查找一个表元素时分为以下3步:
- 在表中查找,如果找到,返回该元素,找不到则继续。
- 判断该表是否有元表,如果没有元表,返回nil,有元表则继续。
- 判断元表有没有index方法,如果index方法为nil,则返回nil;如果index方法是一个表,则重复1,2,3;如果index方法是一个函数,则返回该函数的返回值。
__add
1 | function table_maxn(t) |
2 | local mn = 0 |
3 | for k, v in pairs(t) do |
4 | if mn < k then |
5 | mn = k |
6 | end |
7 | end |
8 | return mn |
9 | end |
10 |
|
11 | arrtable = setmetatable({1,2,3}, { |
12 | __add = function(table1, table2) |
13 | for i = 1, table_maxn(table2) do |
14 | table.insert(table1, table_maxn(table2)+1, table2[i]) |
15 | end |
16 | return table1 |
17 | end |
18 | }) |
19 |
|
20 | secondtable = {4,5,6} |
21 |
|
22 | arrtable = arrtable + secodtable |
23 |
|
24 | for k, v in ipairs(arrtable) do |
25 | print(k,v) |
26 | end |
模块与包
require函数用于加载模块,执行require后返回一个由模块常量或函数组成的table,并且还会定义一个包含该table的全局变量。
1 | module = {} |
2 | module.constant = "this is a const" |
3 |
|
4 | function module.func1() |
5 | io.write("func1()") |
6 | end |
7 |
|
8 | local function func2() |
9 | print("this is a private func") |
10 | end |
11 |
|
12 | function module.func3() |
13 | func2() |
14 | end |
15 |
|
16 | return module |
1 | require("module") |
2 | print(module.constant) |
3 | module.func3() |
4 |
|
5 | local m = require("module") |
6 | print(m.constant) |
7 | m.func3() |
协程
| 方法 |
描述 |
| coroutine.create() |
创建coroutine,返回coroutine,参数是一个函数 |
| coroutine.resume() |
重启coroutine,和create配合使用,启动coroutine |
| coroutine.yield() |
挂起coroutine,将coroutine设置为挂起状态 |
| coroutine.status() |
查看coroutine的状态(dead, suspended, running) |
| coroutine.wrap() |
创建coroutine,返回一个函数,调用该函数,进入coroutine,与create功能重复 |
| coroutine.running() |
返回正在跑的coroutine的线程号 |
1 | local newProductor |
2 |
|
3 | function productor() |
4 | local i = 0 |
5 | while true do |
6 | i = i + 1 |
7 | send(i) |
8 | end |
9 | end |
10 |
|
11 | function consumer() |
12 | while true do |
13 | local i =receive() |
14 | end |
15 | end |
16 |
|
17 | function receive() |
18 | local status, value = coroutine.resume(newProductor) |
19 | return value |
20 | end |
21 |
|
22 | function sed(x) |
23 | coroutine.yield(x) |
24 | end |
25 |
|
26 | newProductor = coroutine.create(productor) |
27 | consumer() |
错误处理
语法错误,运行错误。
assert
assert检查第一个参数,若正确,不做任何事,否则返回第二个参数为错误信息。
1 | local function cool(a) |
2 | assert(type(a) == "number", "a不是一个数字") |
3 | return a |
4 | end |
error
终止正在执行的函数,并返回message的内容作为错误信息。
1 | error (message [, level]) |
2 |
|
3 |
|
4 |
|
面向对象
1 | Shape = {area = 0} |
2 |
|
3 | function Shape:new(o, side) |
4 | o = o or {} |
5 | setmetatable(o, self) |
6 | self.__index = self |
7 | side = side or 0 |
8 | self.area = side * side; |
9 | return o |
10 | end |
11 |
|
12 | function Shape:printArea() |
13 | print("area is: ",self.area) |
14 | end |
15 | myshape = Shape:new(nil,10) |
16 | myshape:printArea() |
17 |
|
18 |
|
19 | Rectangle = Shape:new() |
20 |
|
21 | function Rectangle:new(o, length, breadth) |
22 | o = o or Shape:new(o) |
23 | setmetatable(o, self) |
24 | self.__index = self |
25 | self.area = length * breadth |
26 | return o |
27 | end |
28 |
|
29 | function Rectangle:printArea() |
30 | print("Rectangle area is: ",self.area) |
31 | end |
32 |
|
33 | myrectangle = Rectangle:new(nil, 10, 20) |
34 | myrectangle:printArea() |
参考连接