Base
lua,动态类型语言。lua有8种基础类型:nil/boolean/number(实数)/string/userdata(自定义类型)/function/thread(线程)/table(表)。
可用type函数得到一个值的类型,type的返回值是一个string。
lua中变量没有预定义的类型,任何变量可包含任何类型的值。注意函数也是一种值:
a= print
a("helloworld!")
Type
nil,它只有一个值nil,主要功能用于区别其他任何值。表示“无效值(non-value)”的情况。
boolean,lua中nil和false表示false,其它任何值包括0都不是false
number,实数,lua默认没有整数类型,但通过重新编译来使用其他类型。详见luaconf.h文件。书写一个数字时,可用普通表示法或科学计数法皆可:
4 0.4 4.57e-3
function是第一类值,可存放于变量中,作为参数或返回值。
userdata可以将任意C语言数据存放在其中。该类型只能进行赋值和相等性测试。
thread 将在后面详解
string
string,lua中的字符串通常表示“一个字符序列”。lua完全采用8位编码,lua字符串中的字符可以具有任何数值的编码,包括数值0。即可将任意二进制数据存入string中,注意lua中的字符串是不可变的值,不能修改它的某个字符,而应创建一个新的满足需要的字符串:
a= "one string"
b= string.gsub(a,"one","another") //b 是 “another string”
无须担心字符串(甚到table和function)的分配和释放,lua处理这些事。lua字符串可装很大的数据,lua可以高效处理长字符串,在lua中操作100k或1M字符串是很常见的。
lua中有类似C/C++的转义序列。还可以将数字转为编码,如:\10 相当于\n,注意最多只能有三个数字,即八进制转义。
另,可以用一对匹配的方括号来界定一个字母字符串,就像写“块注释”一样,lua不会对它进行任何解释(如转义序列等):
page= [[
<html>
......
</html>
]]
有人问,要是[[]]中有注释的结束括号]]怎么办,我们可以在[与[之间加上任意的等号如:
[===[,那么该起始括号只有遇到有相同等号的结束符]===]才会结束(对于注释也可以采用该方法)。
lua提供了数字与字符串自动转换。只要字符串可被转化为数字(字符串中甚至可以是一个算术表达式):
print("-5.3e-10"*"2.0") -->-1.06e-09
在任何需要数字的地方,lua都会进行这种转换。在任何需要字符串的地方,lua也会把数字自动转换为字符串:
print(10 .. 20) --> 1020 注意“..”前后要留空格,不然可能会被当成小数点
lua中“..”是字符串连接操作符。
但请不要依赖这种转换,尽量少用,因为毕竟10 == "10"的结果是false,我们如果一定要转换,我们应该明确调用tonumber将string转为number。如果参数string无法转化为number,该函数返回nil。同样,tostring可将number转换为string,我们还可以将一个数字和一个空字符串相连来将number转为string:
10.. ""
在字符串前放一个#可得到字符串的长度:
a= "hello"
print(#a )
print(#"good\0bye")
table
table类型实现了“关联数组”,可用number、string或其它类型的值(除了nil)来索引它。table无固定大小。基于table可以一种简单高效地方式来表示普通数组、符号表(symbol table)、集合,记录、队列和其他数据结构。lua本身通过table表示模块(module)、包(package)和对象(object)。当输入io.read时,其含义是“io模块中的read函数”。对于lua而言,这表示使用字符串“read”作为key来索引table io。
在lua中,table不是“值”或“变量”,而是“对象”。程序仅持有一个对它们的引用或指针,lua不会暗中生成table的副本或新的table。此外,在lua中也不需要声明一个table,事实上也无法声明table。table的创建通过构造表达式来完成。最简单的构造表达式就是{}。
a= {}
k= "x"
a[k]= 10 --> 相当于 a["x"] = 10
a[20]= "great"
print(a["x"])
k= 20
print(a[k]) --> great
a["x"]= a["x"] + 1
print(a["x"]) --> 11
table永远是匿名的,一个持有table的变量和table自身之间没有固定的关联性,当一个程序再也没有一个table的引用时(其它引用都被赋为nil或其他值了),lua的垃圾收集器最终删除该table,并复用它的内存。
当table的某个元素未初始化时,它的值为nil,如果直接:
print(a["hello"]) --> nil
将会输出nil,我们可以把nil赋值table中的某个值来删除那个值。实际上lua正是将全局变量存储在table中。
对于字符串索引,如a["hello"],实际上等价于a.hello。这是lua的语法糖。
在lua中,通常以1作为索引的起始值。#操作符用于返回一个数组或线性表的最后一个索引值,如果是空的它会返回0。但别忘了lua中数组或线性表都是由table实现的,那么,就有可能出现:
a= {}
a[100]= 100
这种情况,对于索引不连续的情况(没有1,2...只有100),#不能正确识别,它会返回第一个索引处值为nil的索引值减1。如对于述a,#a先得到a[1]值为nil,则返回1-1 即0。对于这种数组,要得到它的最大值,可以用table.maxn函数。