开学要去魔都某游戏公司实习了,客户端要用到lua语言,因此寒假前在学校借了《Lua程序设计》,这本书用来入门挺不错的~
类型与值
在Lua语言中,只有nil和false为假(false),其他都为真(true),包括0和空的字符串也是真。
nil
number
print(type(2))
print(type(2.2))
print(type(2e+1))
*注: lua中type函数用来返回参数的类型,它返回的类型是一个字符串。
string
a = "hello world"
b = string.gsub(a, "hello", "hi")
print(a) --> hello world
print(b) --> hi world
Lua语言可以用两个双引号" "来表示字符串,也可以用两个单引号' '来表示,在双引号表示的字符串中如果有双引号,则需要用转义符表示,即:\"表示"
Lua中的转义序列有:
还可以在字符中用\ddd(ddd为三位十进制数字)的方式来表示字母: "alo\n123\""和'\97lo\10\04923"'是相同的.
还可以使用 [[ ... ]] 来表示“一块”字符串:
html = [[
<html>
<head></head>
<body>
<a href="http://www.w3cschool.cc/">w3cschool菜鸟教程</a>
</body>
</html>
]]
这种形式的字符串可以包含多行,可以嵌套且不会解释转义序列,如果第一个字符是换行符则被忽略。
运行时,Lua会在string和number之间自动进行类型转换,当一个字符串使用算数操作符时,string被转成数字:
print("10" + 1) -->11
print("10 + 1") --> 10 + 1
print("hi" + 1) -->ERROR
Lua可以使用 ".." 来 将字符串连接,因此:
print(10 .. 20) -->1020
要注意的是, .. 前的数字必须和..之间有空格,不然lua解释器会认为是小数点。
tonumber()可以将一个字符串转换为数字,tostring则可以将一个数字转换为而字符串:
print(tostring(10) == “10”) -->true
print(20 == tonumber("20")) -->true
Function
userdata和thread
在 Lua 里,最主要的线程是协同程序(coroutine)。它跟线程(thread)差不多,拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。
线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停。
table
在Lua中,table既不是“值”也是不是“变量”, 而是“对象”。 table就像是一个动态的对象,程序仅持有一个对它们的引用(或指针)。在Lua中不需要声明一个table,事实上也没办法声明它,我们可以通过“构造表达式”来完成一个table的定义,最简单的就是一个空的大括号:{}
a = {}
k = "x"
a[k] = 10
a[20] = "hello"
print(a["x"]) --> 10
k = 20
print(a[k]) --> "hello"
a["x"] = a["x"] + 1
print(a["x"]) --> 11
table永远是”匿名的“, 一个持有table的变量与table自身之间没有固定的关联性:
a = {}
a["x"] = 10
b = a --> b和a引用了同一个table
print(b["x"]) --> 10
b["x"] = 20
print(a["x"]) --> 20
a = nil --> 现在还有b在引用table
b = nil --> 再也没有对table的引用了
一个程序中再也没有对一个table的引用时,Lua的垃圾收集器最终会删除该table,并复用它的内存。
a = {}
a["x"] = 10
print(a["x"]) --> 10
print(a["y"]) --> nil
当table中的某个元素没有初始化时,它的值为nil。 也可以像全局变量一样,赋予table中某个元素为nil,从而删除这个元素。
table中对于诸如a["name"] 的写法提供了一种更简便的方式,可以直接输入 a.name。因此,可以这样写:
a.x = 10
print(a.x) --> 相当于a["x"]
print(a.y) --> 相当于a["y"]
需要注意的是,a.x 和 a[x] 不相同, a.x 的意思是 a["x"] ,是以x为索引; 而a[x]的意思是以x的值为索引,假如x的值为10,则a[x]表示a[10]。
a = {}
x = "y"
a[x] = 10
print(a[x]) --> 10 即a["y"]字段
print(a.x) --> nil a中没有"x"这个索引
print(a.y) --> 10
在Lua5.1中,"#"可以返回一个数组或线性表的最后一个索引值(或为其大小)。例如:
for i = 1, 10 do
a[i] = io.read()
end
--上面也可以这么写
for i = 1, 10 do
a[#a + 1] = io.read()
end
-- 打印读到的所有内容
for i = 1, #a do
print(a[i])
end
其他一些#的用法:
print(a[#a]) --> 打印列表a的最后一个值
a[#a] = nil --> 删除最后一个值
a[#a + 1] --> 将v添加到列表末尾
数组实际上是一个table,当用#来计算大小时,有时候会有意想不到的结果:
a = {}
a[1] = 1
a[10] = 10
print(#a) --> 1
而数组的实际大小为2,这是因为#计算到第一个nil值之前,当一个数组中间有“空隙”, 即中间含有nil时,#就认为数组就这么大了。这跟我们的初衷可能不太一样。
我们可以使用table函数maxn,它返回一个table的最大索引数:
print(table.maxn(a)) --> 10
关于table还有很多内容,后面再从长议论。
表达式
算数运算符
关系运算符
这些操作符返回true或者false。 == 和 ~=比较两个值,如果两个值类型不同,Lua认为两者不同; nil只和自己相等;Lua通过引用来比较table、userdata和function,也就是说当且仅当两者引用同一个对象时才相等。
a = {}; a.x = 1; a.y = 0
b = {}; b.x = 1; b.y = 0
c = a
print(a == c) --> true 引用同一个对象
print(b == c) --> false
Lua比较数字时按传统的数字大小进行,比较字符串按字母的顺序进行。
"0" == 0 --> false
2 < 15 --> true
"2" < "15" --> false
最后一个是比较两个字符串,因为"1"比"2"小,所以"2"应该大于"15"。
逻辑运算符
逻辑认为false和nil为假,其他为真,0也是true。
a and b --> 如果a为false,则返回a,否则返回b
a or b --> 如果a为true,则返回b,否则返回b
print (4 and 5) --> 返回5
print (nil and 5) --> 返回nil
print(4 or 5) -->返回4
print(false or 5) --> 5
很实用的一个技巧,当x为false或nil时,将a赋给x:
x = x or a
C语言中的三目运算符 a ? b : c ,在Lua中可以这么写:
(a and b) or c
a为true,则(a and b)的值为b,与c作 or运算,返回b;
a为false,则(a and b)的值为a, 与c作or运算,返回c。
not的结果一直返回true或false
print(not nil) --> true
print(not false) -->true
print(not true) -->false
print(not 0) -->false
运算符优先级(由高到低)
基本语法
赋值语句
str = "hello" .. "world"
t.n = t.n + 1
Lua语言中,还可以对多个变量同时赋值, 变量列表和值列表用逗号隔开,赋值语句右边的值依次赋值给左边的变量:
a, b = 10, 20 --> a为10,b为20
可以利用这个特性来进行交换操作:
x, y = y, x
赋值语句会先计算右边所有的值,然后进行赋值。
控制语句结构
if语句
while语句
repeat-until语句
如果condition为真,则退出语句。
for语句
三个表达式exp只会被计算一次,在循环开始之前。
第二类:泛型for
① for k, v in ipairs(t) do print(k .. v) end
② for k, v in pairs(t) do print(k .. v) end
t为table类型
第一类泛型for,用于遍历数组,而且下标从1开始并且是连续索引值的数组。
如果索引值不是数字,或者不连续,它都只打印从索引1开始连续的部分:
第二类泛型for则可以打印出所有的元素,但是顺序不规则:
可见,它打印的顺序似乎并不是我们添加的顺序,因为table用哈希表实现,对于非数组形式的table,打印出的顺序和添加的顺序就不一样了。