Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。 Lua 是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo所组成并于1993年开发。
Lua 应用场景 游戏开发 独立应用脚本 Web 应用脚本 扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench 安全系统,如入侵检测系统
Hello world!
注释
变量 全局变量 默认即为全局变量,无需声明符号
访问未定义的全局变量不出错 *删除全局变量将其赋值为nil(等同于其他语言NULL)即可1
2
3
4
5
a=10
print (a)
a=nil
print (a)
局部变量
局部变量的作用域为从声明位置开始到所在语句块结束(或者是直到下一个同名局部变量的声明)。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
local data = 100 ;
local function fun1 ()
print (data);
data = data+50 ;
end
data = 200 ;
local data = 300 ;
local function fun2 ()
print (data);
data = data+50 ;
end
data = 400 ;
fun1();
fun2();
fun1();
fun2();
赋值 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
a, b = 10 , 2 *x
x, y = y, x
a[i], a[j] = a[j], a[i]
-[[赋值多个的时候,如下规则
a. 变量个数 > 值的个数 按变量个数补足nil
b. 变量个数 < 值的个数 多余的值会被忽略
]]
a, b, c = 0 , 1
print (a,b,c)
a, b = a+1 , b+1 , b+2
print (a,b)
a, b, c = 0
print (a,b,c)
索引 1
2
3
t[i]
t.i
gettable_event(t,i)
数据类型
类型
说明
nil
这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。
boolean
包含两个值:false和true。
number
表示双精度类型的实浮点数
string
字符串由一对双引号或单引号来表示
function
由 C 或 Lua 编写的函数
userdata
表示任意存储在变量中的C数据结构
thread
表示执行的独立线路,用于执行协同程序
table Lua
中的表(table)其实是一个”关联数组”(associative arrays),数组的索引可以是数字或者是字符串。在 Lua 里,table 的创建是通过”构造表达式”来完成,最简单构造表达式是{},用来创建一个空表。
1
2
3
4
5
6
7
8
print (type ("Hello world" ))
print (type (10.4 *3 ))
print (type (print ))
print (type (type ))
print (type (true ))
print (type (nil ))
print (type (type (X)))
nil nil 类型表示一种没有任何有效值,它只有一个值 – nil,例如打印一个没有赋值的变量,便会输出一个 nil 值:
对于全局变量和 table,nil 还有一个”删除”作用,给全局变量或者 table 表里的变量赋一个 nil 值,等同于把它们删掉,执行下面代码就知:1
2
3
4
5
6
7
8
9
tab1 = { key1 = "val1" , key2 = "val2" , "val3" }
for k, v in pairs (tab1) do
print (k .. " - " .. v)
end
tab1.key1 = nil
for k, v in pairs (tab1) do
print (k .. " - " .. v)
end
bool类型
boolean 类型只有两个可选值:true(真) 和 false(假),Lua 把 false 和 nil 看作是”假”,其他的都为”真”:1
2
3
4
5
6
7
8
9
print (type (true ))
print (type (false ))
print (type (nil ))
if false or nil then
print ("至少有一个是 true" )
else
print ("false 和 nil 都为 false!" )
end
number
Lua 默认只有一种 number 类型 – double(双精度)类型(默认类型可以修改 luaconf.h 里的定义),1
2
3
4
5
6
print (type (2 ))
print (type (2.2 ))
print (type (0.2 ))
print (type (2e+1 ))
print (type (0.2e-1 ))
print (type (7.8263692594256e-06 ))
string 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
string1 = "this is string1"
html = [[
<html>
<head></head>
<body>
<a href="http://www.w3cschool.cc/">w3cschool菜鸟教程</a>
</body>
</html>
]]
print (html)
print ("1" +2 )
print ("1" .."2" )
print (#html)
table(表)
在 Lua 里,table (类似于map,将list与map结合起来)的创建是通过”构造表达式”来完成,最简单构造表达式是{},用来创建一个空表。也可以在表里添加一些数据,直接初始化表:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
local tbl1 = {}
local tbl2 = {"apple" , "pear" , "orange" , "grape" }
for key, val in pairs (tbl2) do
print ("Key" , key, val)
end
a = {}
a["key" ] = "value"
key = 10
a[key] = 22
a[key] = a[key] + 11
for k, v in pairs (a) do
print (k .. " : " .. v)
end
table 不会固定长度大小,有新数据添加时 table 长度会自动增长,没初始的 table 都是 nil。1
2
3
4
5
6
7
a3 = {}
for i = 1 , 10 do
a3[i] = i
end
a3["key" ] = "val"
print (a3["key" ])
print (a3["none" ])
function(函数)
1
2
3
4
5
6
7
8
9
10
11
function factorial1 (n)
if n == 0 then
return 1
else
return n * factorial1(n - 1 )
end
end
print (factorial1(5 ))
factorial2 = factorial1
print (factorial2(5 ))
*function 可以以匿名函数(anonymous function)的方式通过参数传递:1
2
3
4
5
6
7
8
9
function anonymous (tab, fun)
for k, v in pairs (tab) do
print (fun(k, v))
end
end
tab = { key1 = "val1" , key2 = "val2" }
anonymous(tab, function (key, val)
return key .. " = " .. val
end )
thread(线程) 在 Lua 里,最主要的线程是协同程序(coroutine)。它跟线程(thread)差不多,拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。 线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停。
userdata(自定义类型)
userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的类型,可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中调用。
循环 while 1
2
3
4
5
6
a=10
while ( a < 20 )
do
print ("a 的值为:" , a)
a = a+1
end
for 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
for var=exp1,exp2,exp3 do
<执行体>
end
for i=1 ,f(x) do
print (i)
end
for i=10 ,1 ,-1 do
print (i)
end
function f (x)
print ("function" )
return x*2
end
for i=1 ,f(5 ) do print (i)
end
function
1
2
3
4
5
6
7
8
9
10
--]]
泛型for循环 1
2
3
4
5
6
a = {"Lua" , "Tutorial" }
for i,v in ipairs (a)
do print (i..v)
end
repeat…until(类似do while) 1
2
3
4
5
6
7
a = 10
repeat
print ("a的值为:" , a)
a = a + 1
until ( a > 15 )
不同循环可以嵌套 1
2
3
4
5
6
7
8
9
10
11
12
j =2
for i=2 ,10 do
for j=2 ,(i/j) , 2 do
if (not (i%j))
then
break
end
if (j > (i/j))then
print ("i 的值为:" ,i)
end
end
end
break 1
2
3
4
5
6
7
8
9
10
11
12
13
14
a = 10
while ( a < 20 )
do
print ("a 的值为:" , a)
a=a+1
if ( a > 15 )
then
break
end
end
流程控制 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
a = 100
if ( a == 10 )
then
print ("a 的值为 10" )
else if ( a == 20 )
then
print ("a 的值为 20" )
else if ( a == 30 )
then
print ("a 的值为 30" )
else
print ("没有匹配 a 的值" )
end
print ("a 的真实值为: " , a )
函数 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function max (num1, num2)
if (num1 > num2) then
result = num1;
else
result = num2;
end
return result;
end
print ("两值比较最大值为 " ,max(10 ,4 ))
print ("两值比较最大值为 " ,max(5 ,6 ))
函数作为参数 1
2
3
4
5
6
7
8
9
10
11
12
myprint = function (param)
print ("这是打印函数 - ##" ,param,"##" )
end
function add (num1,num2,functionPrint)
result = num1 + num2
functionPrint(result)
end
myprint(10 )
add(2 ,5 ,myprint)
多返回值 1
s, e = string .find("w3cschool菜鸟教程:www.w3cschool.cc" , "菜鸟教程" ) print (s,e)
1
2
3
4
5
6
7
8
9
10
11
12
13
function maximum (a)
local mi = 1
local m = a[mi]
for i,val in ipairs (a) do
if val > m then
mi = i
m = val
end
end
return m, mi
end
print (maximum({8 ,10 ,23 ,12 ,5 }))
可变参数 1
2
3
4
5
6
7
8
9
10
11
12
function average (...)
result = 0
local arg={...}
for i,v in ipairs (arg) do
result = result + v
end
print ("总共传入 " .. #arg .. " 个数" )
return result/#arg
end
print ("平均值为" ,average(10 ,5 ,3 ,4 ,5 ,6 ))
运算符 算数 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
a = 21
b = 10
c = a + b
print ("Line 1 - c 的值为 " , c )
c = a - b
print ("Line 2 - c 的值为 " , c )
c = a * b
print ("Line 3 - c 的值为 " , c )
c = a / b
print ("Line 4 - c 的值为 " , c )
c = a % b
print ("Line 5 - c 的值为 " , c )
c = a^2
print ("Line 6 - c 的值为 " , c )
c = -a
print ("Line 7 - c 的值为 " , c )
Line 1 - c 的值为 31
Line 2 - c 的值为 11
Line 3 - c 的值为 210
Line 4 - c 的值为 2.1
Line 5 - c 的值为 1
Line 6 - c 的值为 441
Line 7 - c 的值为 -21
--]]
关系 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
a = 21
b = 10
if ( a == b )
then
print ("Line 1 - a 等于 b" )
else
print ("Line 1 - a 不等于 b" )
end
if ( a ~= b )
then
print ("Line 2 - a 不等于 b" )
else
print ("Line 2 - a 等于 b" )
end
if ( a < b )
then
print ("Line 3 - a 小于 b" )
else
print ("Line 3 - a 大于等于 b" )
end
if ( a > b )
then
print ("Line 4 - a 大于 b" )
else
print ("Line 5 - a 小于等于 b" )
end
a = 5
b = 20
if ( a <= b )
then
print ("Line 5 - a 小于等于 b" )
end
if ( b >= a )
then
print ("Line 6 - b 大于等于 a" )
end
逻辑 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
a = true
b = true
if ( a and b )
then
print ("a and b - 条件为 true" )
end
if ( a or b )
then
print ("a or b - 条件为 true" )
end
print ("---------分割线---------" )
a = false
b = true
if ( a and b )
then
print ("a and b - 条件为 true" )
else
print ("a and b - 条件为 false" )
end
if ( not ( a and b) )
then
print ("not( a and b) - 条件为 true" )
else
print ("not( a and b) - 条件为 false" )
end
特殊 1
2
3
4
5
6
7
8
9
10
a = "Hello "
b = "World"
print ("连接字符串 a 和 b " , a..b )
print ("b 字符串长度 " ,#b )
print ("字符串 Test 长度 " ,#"Test" )
print ("w3cschool菜鸟教程网址长度 " ,#"www.w3cschool.cc" )
字符串 示例 1
2
3
4
5
6
7
string1 = "Lua"
print ("\"字符串 1 是\"" ,string1)
string2 = 'w3cschool.cc'
print ("字符串 2 是" ,string2)
string3 = [["Lua 教程"]]
print ("字符串 3 是" ,string3)
字符串常用操作 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
print (string .upper("abc" ))
print (string .upper("ABC" ))
print (string .gsub("abcabc" ,'c' ,'d' ,1 ))
print (string .find("abcabc" ,'a' ,3 ))
print (string .reverse("12345" ))
string .format("the value is:%d" ,4 )
print (string .char(97 ,98 ,99 ,100 ))
print (string .byte("abc" ,2 ))
print (string .len("abc" )==#"abc" )
print (string .rep('a' , 3 ))
print ("aaa" ..'bbb' )
数组 一维 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
array = {"Lua" , "Tutorial" }
for i= 0 , 2 do
print (array[i])
end
array = {}
for i= -2 , 2 do
array[i] = i *2
end
for i = -2 ,2 do
print (array[i])
end
多维 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
array = {}
for i=1 ,3 do
array[i] = {}
for j=1 ,3 do
array[i][j] = i*j
end
end
for i=1 ,3 do
for j=1 ,3 do
print (array[i][j])
end
end
迭代器 内置简单迭代 1
2
3
4
5
6
array = {"Lua" , "Tutorial" }
for key,value in ipairs (array)
do
print (key, value)
end
自定义的迭代器 1
2
3
4
5
6
7
8
9
10
11
12
function square (iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
for i,n in square,4 ,0
do
print (i,n)
end
利用闭包实现的迭代器 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
array = {"Lua" , "Tutorial" }
function elementIterator (collection)
local index = 0
local count = #collection
return function ()
index = index + 1
if index <= count
then
return collection[index]
end
end
end
for element in elementIterator(array)
do
print (element)
end
Lua table
table 是 Lua 的一种数据结构用来帮助我们创建不同的数据类型,如:数字、字典等。
Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil。
Lua table 是不固定大小的,你可以根据自己需要进行扩容。
Lua也是通过table来解决模块(module)、包(package)和对象(Object)的。 例如string.format表示使用”format”来索引table string。
初始化与销毁 1
2
3
4
5
6
7
8
9
mytable = {}
mytable[1 ]= "Lua"
mytable = nil
table的引用(类似Java) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
mytable = {}
print ("mytable 的类型是 " ,type (mytable))
mytable[1 ]= "Lua"
mytable["wow" ] = "修改前"
print ("mytable 索引为 1 的元素是 " , mytable[1 ])
print ("mytable 索引为 wow 的元素是 " , mytable["wow" ])
alternatetable = mytable
print ("alternatetable 索引为 1 的元素是 " , alternatetable[1 ])
print ("mytable 索引为 wow 的元素是 " , alternatetable["wow" ])
alternatetable["wow" ] = "修改后"
print ("mytable 索引为 wow 的元素是 " , mytable["wow" ])
alternatetable = nil
print ("alternatetable 是 " , alternatetable)
print ("mytable 索引为 wow 的元素是 " , mytable["wow" ])
mytable = nil
print ("mytable 是 " , mytable)
table操作 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
t1={"a" ,"b" ,"c" }
print (table .concat(t1))
print (table .concat(t1,"@@" ))
print (table .concat(t1,"@@" ,1 ,2 ))
table .insert(t1,"d" )
print (t1[4 ])
table .insert(t1,2 ,"b" )
print (t1[2 ])
print ("当前元素:" ..table .concat(t1,"," ))
table .remove(t1)
print ("remove(t1)默认删除最后一个元素,当前元素:" ..table .concat(t1,"," ))
table .remove(t1,1 )
print ("remove(t1,1)之后" ..table .concat(t1,"," ))
t1={"c" ,"b" ,"a" }
print ("排序前:" ..table .concat(t1,"," ))
table .sort(t1)
print ("排序后:" ..table .concat(t1,"," ))
!!!慎用”#table”
不要赋值nil,删除元素请使用remove
元素不是同一类型length无明确意义1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tbl = {"a" , "b" ,"c" }
print ("tbl 长度 " , #tbl)
tbl = {"a" , "b" ,"c" ="bb" }
print ("tbl 长度 " , #tbl)
tbl = {"a" , "b" ,nil }
print ("tbl 长度 " , #tbl)
tbl = {"a" , nil ,"b" ,nil }
print ("tbl 长度 " , #tbl)
模块与包 自定义包 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
module = {}
module .constant = "这是一个常量"
function module.func1 ()
io .write("这是一个公有函数!\n" )
end
local function func2 ()
print ("这是一个私有函数!" )
end
function module.func3 ()
func2()
end
return module
1
2
3
4
5
6
7
8
9
10
11
12
require ("module" )
print (module .constant)
module .func3()
local m = require ("module" )
print (m.constant)
m.func3()
加载策略
require 用于搜索 Lua 文件的路径是存放在全局变量 package.path 中,当 Lua 启动后,会以环境变量LUA_PATH的值来初始这个环境变量。如果没有找到该环境变量,则使用一个编译时定义的默认路径来初始化。1
2
#LUA_PATH
export LUA_PATH="~/lua/?.lua;;"
元表
元表就是在table上加上自定义的对表数据的操作__index 1
2
3
4
5
6
7
8
9
10
11
12
mytable = setmetatable ({key1 = "value1" }, {
__index = function (mytable, key)
if key == "key2" then
return "metatablevalue"
else
return mytable[key]
end
end
})
print (mytable.key1,mytable.key2)
__newindex 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
mymetatable = {}
mytable = setmetatable ({key1 = "value1" }, { __newindex = mymetatable })
print (mytable.key1)
mytable.newkey = "新值2"
print (mytable.newkey,mymetatable.newkey)
mytable.key1 = "新值1"
print (mytable.key1,mymetatable.key1)
mytable = setmetatable ({key1 = "value1" }, {
__newindex = function (mytable, key, value)
rawset (mytable, key, "\"" ..value.."\"" )
end
})
mytable.key1 = "new value"
mytable.key2 = 4
print (mytable.key1,mytable.key2)
__add 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
function table_maxn (t)
local mn = 0
for k, v in pairs (t) do
if mn < k then
mn = k
end
end
return mn
end
mytable = setmetatable ({ 1 , 2 , 3 }, {
__add = function (mytable, newtable)
for i = 1 , table_maxn(newtable) do
table .insert(mytable, table_maxn(mytable)+1 ,newtable[i])
end
return mytable
end
})
secondtable = {4 ,5 ,6 }
mytable = mytable + secondtable
for k,v in ipairs (mytable) do
print ("index:" ..k,v)
end
__add 对应的运算符 '+'.
__sub 对应的运算符 '-'.
__mul 对应的运算符 '*'.
__div 对应的运算符 '/'.
__mod 对应的运算符 '%'.
__unm 对应的运算符 '-'.
__concat 对应的运算符 '..'.
__eq 对应的运算符 '=='.
__lt 对应的运算符 '<'.
__le 对应的运算符 '<='.
--]]
__call 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function table_maxn (t)
local mn = 0
for k, v in pairs (t) do
if mn < k then
mn = k
end
end
return mn
end
mytable = setmetatable ({10 }, {
__call = function (mytable, newtable)
sum = 0
for i = 1 , table_maxn(mytable) do
sum = sum + mytable[i]
end
for i = 1 , table_maxn(newtable) do
sum = sum + newtable[i]
end
return sum
end
})
newtable = {10 ,20 ,30 }
print (mytable(newtable))
__tostring 1
2
3
4
5
6
7
8
9
10
11
mytable = setmetatable ({ 10 , 20 , 30 }, {
__tostring = function (mytable)
sum = 0
for k, v in pairs (mytable) do
sum = sum + v
end
return "表所有元素的和为 " .. sum
end
})
print (mytable)
协同(coroutine) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
co = coroutine .create(
function (i)
print (i);
end
)
print (coroutine .status(co))
coroutine .resume(co, 1 )
print (coroutine .status(co))
print ("----------" )
co = coroutine .wrap(
function (i)
print (i);
end
)
co(1 )
print ("----------" )
co2 = coroutine .create(
function ()
for i=1 ,10 do
print (i)
if i == 3 then
print (coroutine .status(co2))
print (coroutine .running())
end
coroutine .yield()
end
end
)
coroutine .resume(co2)
coroutine .resume(co2)
coroutine .resume(co2)
print (coroutine .status(co2))
print (coroutine .running())
print ("----------" )
resume与create的配合 注意resume与yield的参数传递 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function foo (a)
print ("foo 函数输出" , a)
return coroutine .yield(2 * a)
end
co = coroutine .create(function (a , b)
print ("第一次协同程序执行输出" , a, b)
local r = foo(a + 1 )
print ("第二次协同程序执行输出" , r)
local r, s = coroutine .yield(a + b, a - b)
print ("第三次协同程序执行输出" , r, s)
return b, "结束协同程序"
end )
print ("main" , coroutine .resume(co, 1 , 10 ))
print ("main" , coroutine .resume(co, "r" ))
print ("main" , coroutine .resume(co, "x" , "y" ))
print ("main" , coroutine .resume(co, "x" , "y" ))
生产者-消费者 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
local newProductor
function productor ()
local i = 0
while true do
i = i + 1
send(i)
end
end
function consumer ()
while true do
local i = receive()
print (i)
end
end
function receive ()
local status, value = coroutine .resume(newProductor)
return value
end
function send (x)
coroutine .yield(x)
end
newProductor = coroutine .create(productor)
consumer()
IO 简单模式(类c语言) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
file = io.open (filename [, mode])
r 以只读方式打开文件,该文件必须存在。
w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
r+ 以可读写方式打开文件,该文件必须存在。
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a+ 与a类似,但此文件可读可写
b 二进制模式,如果文件是二进制文件,可以加上b
+ 号表示对文件既可以读也可以写
--]]
file = io .open("test.txt" , "r" )
io .input(file)
print (io .read("*n" ))
print (io .read(2 ))
print (io .read("*l" ))
print (io .read("*a" ))
io .close(file)
file = io .open("test.lua" , "a" )
io .output(file)
io .write("-- test.lua 文件末尾注释" )
io .close(file)
其他的IO函数
io.tmpfile():返回一个临时文件句柄,该文件以更新模式打开,程序结束时自动删除
io.type(file): 检测obj是否一个可用的文件句柄
io.flush(): 向文件写入缓冲中的所有数据
io.lines(optional file name):返回一个迭代函数,每次调用将获得文件中的一行内容,当到文件尾时,将返回nil,但不关闭文件
完全模式 IO.xxx变为file.xxx 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
file = io .open("test.lua" , "r" )
print (file:read())
file:close()
file = io .open("test.lua" , "a" )
file:write("--test" )
file:close()
file:seek(optional whence, optional offset) 设置和获取当前文件位置
file:flush(): 向文件写入缓冲中的所有数据
io.lines(optional file name)打开指定的文件filename为读模式并返回一个迭代函数,每次调用将获得文件中的一行内容,当到文件尾时,将返回nil,并自动关闭文件。1
2
3
4
5
6
7
8
file = io .open("test.lua" , "r" )
file:seek("end" ,-25 )
print (file:read("*a" ))
file:close()
1
2
3
4
5
for line in io .lines("test.lua" ) do
print (line)
end
错误处理 assert与error 1
2
3
4
5
6
7
8
9
10
11
12
13
local function add (a,b)
assert (type (a) == "number" , "a is not a number" )
assert (type (b) == "number" , "b is not a number" )
if (a==b) then
error ("err" ,2 )
end
return a+b
end
print (add(10 ,20 ))
pcall与xpcall 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
pcall (function (i) print (i) end , aa==1 )
has_err,err_info=pcall (function (i) print (i) error ('error..' ) end , 33 )
print (has_err,err_info)
function myfunction ()
n = n/nil
end
function myerrorhandler ( err )
print ( "ERROR:" , err )
end
status = xpcall ( myfunction, myerrorhandler )
print ( status)
垃圾回收 lua为自动垃圾回收
collectgarbage(“collect”): 做一次完整的垃圾收集循环。通过参数 opt 它提供了一组不同的功能:
collectgarbage(“count”): 以 K 字节数为单位返回 Lua 使用的总内存数。 这个值有小数部分,所以只需要乘上 1024 就能得到 Lua 使用的准确字节数(除非溢出)。
collectgarbage(“restart”): 重启垃圾收集器的自动运行。
collectgarbage(“setpause”): 将 arg 设为收集器的 间歇率 (参见 §2.5)。 返回 间歇率 的前一个值。
collectgarbage(“setstepmul”): 返回 步进倍率 的前一个值。
collectgarbage(“step”): 单步运行垃圾收集器。 步长”大小”由 arg 控制。 传入 0 时,收集器步进(不可分割的)一步。 传入非 0 值, 收集器收集相当于 Lua 分配这些多(K 字节)内存的工作。 如果收集器结束一个循环将返回 true 。
collectgarbage(“stop”): 停止垃圾收集器的运行。 在调用重启前,收集器只会因显式的调用运行。
面向对象 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Shape = {area = 0 }
function Shape:new (o,side)
o = o or {}
setmetatable (o, self)
self.__index = self
side = side or 0
self.area = side*side;
return o
end
function Shape:printArea ()
print ("面积为 " ,self.area)
end
myshape = Shape:new(nil ,10 )
myshape:printArea()
继承与方法重写 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Shape = {area = 0 }
function Shape:new (o,side)
o = o or {}
setmetatable (o, self)
self.__index = self
side = side or 0
self.area = side*side;
return o
end
function Shape:printArea ()
print ("面积为 " ,self.area)
end
myshape = Shape:new(nil ,10 )
myshape:printArea()
Square = Shape:new()
function Square:new (o,side)
o = o or Shape:new(o,side)
setmetatable (o, self)
self.__index = self
return o
end
function Square:printArea ()
print ("正方形面积为 " ,self.area)
end
mysquare = Square:new(nil ,10 )
mysquare:printArea()
Rectangle = Shape:new()
function Rectangle:new (o,length,breadth)
o = o or Shape:new(o)
setmetatable (o, self)
self.__index = self
self.area = length * breadth
return o
end
function Rectangle:printArea ()
print ("矩形面积为 " ,self.area)
end
myrectangle = Rectangle:new(nil ,10 ,20 )
myrectangle:printArea()