一、Lua基础知识
Lua区分大小写。
几条连续的Lua语句之间不需要分割,如果需要可以用分号;分割。
一般约定以下划线开头连接一串大写字母变量(比如 _VERSION)被保留用于 Lua 内部全局变量。
默认情况,变量总是全局的。
全局变量不需要声明,给一个变量赋值后即创建了这个全局变量。
访问一个没有初始化的全局变量返回结果是nil。
删除一个全局变量,只需要将变量赋值为nil。
当且仅当一个变量不等于nil时,这个变量即存在。
字符串由一对双引号或单引号来表示。
function是一种数据类型,表示C或Lua编写的函数。函数可以存在变量里。
给全局变量赋一个nil值,等同于把它们删掉。
Lua把false和nil看作是"假",其他的都为"真"。
以用2个方括号"[[]]"来表示"一块"字符串。
字符串连接使用的是..,在数字后面使用时要加个空格。
尽量避免使用强制转换,可以使用函数tonumber将字符串转为数字(无法转换返回nil),tostring将数字转为字符串。
使用#来计算字符串或表的长度,放在前面#str。a["name"]可以写作a.name 。
在Lua里表的默认初始索引一般以1开始。
Lua函数可以存储在变量中,可以通过参数传递给其他函数,可以作为其他函数的返回值。
Lua函数可以返回多个值,每个值以逗号隔开。
Lua函数可以接受可变数目的参数,在函数参数列表中使用三点(...) 表示函数有可变的参数。
Lua将可变函数的参数放在一个叫arg的表中,#arg表示传入参数的个数。
Lua脚本执行:lua luascript.lua
==用于相等性测试,~=用于不等性测试。nil只与自身相等。
多重赋值中,Lua先对等号右边所有元素求值,然后才进行赋值:x,y = y,x 等同于交换x y变量的值。
使用do-end,可以显示的界定一个程序块,lua不会单独执行do后面的每行内容,直至遇到一个相应的end。
尽可能的使用局部变量。
break和return只能是程序块的最后一条语句,如果想要放在其他位置,需要显示的do-end包住一个return。
lua函数出现在一个表达式中,lua会把函数的返回值数量调整为1。table构造式{}可以完整的接收一个函数调用的所有结果,不会有任何数量方面的调整。但仅限于函数调用作为table最后一个元素时才会发生,其他位置的函数调用仅产生一个结果值。可以将函数调用放入一对()中,从而迫使他只返回一个结果:(foo())
unpack函数
(lua 5.2)
二、关于table表
1、先定义一个空table:
-- 定义一个全局的table test_table = {} -- 打印出来,结果是table的地址 print(test_table) -- 输出结果 table: 0073B1C8
然后可以给table赋值:
test_table[1]="a"
test_table[2]="b"
test_table[3]="c"
for k,v in pairs(test_table) do
print( test_table[k] )
end
输出为a,b,c。
2、当然也可以这样定义key为字符串:
test_table = {[1]="a",[2]="b",[3]="c",["str1"]="d",["str2"]="e"}
for k,v in pairs(test_table) do
print( k,"-",v )
end
这时打印结果为:
str2 - e
2 - b
3 - c
1 - a
str1 - d
发现其实并不是按照顺序打印的:原因是pairs方法是根据key的hash值进行遍历的,不能保证顺序,但是却可以遍历table的全部key。
3、如果换成ipairs方法:
for k,v in ipairs(test_table) do
print( k,"-",v )
end
结果为:
1 - a
2 - b
3 - c
原因是ipairs方法,只会遍历key是整数,且从1开始key连续的数据(如果没有从1开始,或者不连续的key是不会遍历的)。换一种方式:
for i=1, #(test_table) do
print(test_table[i])
end
和ipairs遍历结果一致,#(test_table)代表获取table的长度,不过:
test_table = {[1]="a",[2]="b",[3]="c",[5]="f",["str1"]="d",["str2"]="e"}
print(#(test_table)) --此处返回3,而不是6
#(test_table)也只会取key是整数,且从1开始key连续的数据(5虽然是整数key,但不连续)。
如果没有key为1的数据,则#(test_table)结果为0。
注意:
不要在lua的table中使用nil值,如果一个元素要删除,直接remove,不要用nil去代替。
原因看这里:http://www.jb51.net/article/64668.htm
5、table中删除元素:
table.remove(test_table) --删除整数索引的最后一个 table.remove(test_table,pos) --删除整数索引的第pos位置的
删除以后,后面的元素会向前移动。
6、如果table声明时不指定key:
test_table={"a","b","c","d","e"}
for k,v in ipairs(test_table) do
print( k,"-",v )
end
这样其实是默认从1开始为key赋值,返回结果为:
1 - a
2 - b
3 - c
4 - d
5 - e
7、如果出现了字符串key与整数key混搭的情况:
test_table={"a","b",["string1"]="str1","c","d","e","f",["string2"]="str2",string3="str3",[8]="h"}
for k,v in pairs(test_table) do -- pairs遍历
print( k,"-",v )
end
结果为:
1 - a
2 - b
3 - c
4 - d
5 - e
6 - f
8 - h
string2 - str2
string3 - str3
string1 - str1
可以看出这里key为string3的声明方式,直接使用了字面量,与["string3"]="str3"是相同的。
如果换做ipairs方式遍历结果为:
1 - a
2 - b
3 - c
4 - d
5 - e
6 - f
发现声明的[8]="h"并没有打印,因为前面的a、b、c、d、e、f整数索引是自动生成的,可以保证连续性,这里手工指定的并不连续。
8、如果手工赋值与自动生成整型key同时使用:
test_table={"a","b","c","d","e","f",[1]="x",[2]="x",[3]="x",[4]="x",[5]="x",[6]="x"}
for k,v in pairs(test_table) do
print( k,"-",v )
end
pairs遍历结果:
1 - a
2 - b
3 - c
4 - d
5 - e
6 - f
可见手工赋值并没有起作用(虽然赋值是在最后)。
9、table的遍历
上面介绍了3种table的遍历方式:
--pairs (可以遍历全部元素,包括string型key)
for k,v in pairs(test_table) do
print( k,"-",v )
end
--ipairs(只能遍历整型key)
for k,v in ipairs(test_table) do
print( k,"-",v )
end
--计数(只能遍历整型key)
for i=1, 10 do
print(test_table[i])
end
10、table连接:
test_table={"a","b","c",[4]="d",[5]="e",[6]="f",["str1"]="x2",str2="x1",[3]="x",[4]="x"}
print(table.concat(test_table))
table.concat 函数可以连接table中的数组部分的元素,上面程序执行的结果为:abcxef
其中d变为了x,是因为后面对4位置重新进行了赋值。但c因为是自动生成的整型key,所以没有被替换为x。
如果数组部分的key不连续,比如test_table后面又加了[8]="i"(但其实没有key=7的位置),这样使用table.concat就会报错,如:invalid value (nil) at index 7 in table for 'concat'
str1和str2的key没有被连接,是因为这里并不是整型key,不算做数组部分的元素。
11、table排序:
给定的table进行升序排序,其他排序可以通过比较器实现。
http://www.jb51.net/article/55718.htm 排序实例
12、table取最大值:
Lua5.2之后table.maxn方法已经不存在了: