一、Lua程序执行环境
(1)交互模式
下载LuaForWindows安装即可。交互模式下会对可执行的程序块(语句)立即执行。
在交互模式下也可以用dofile(“filename”)来执行脚本文件。
调用os.exit()或linux下ctrl+d,Windows下ctrl+z退出交互模式
(2)命令模式
Windows下安装LuaForWindows后会自动添加环境变量。用“lua”作为指令
lua [-ile] filename [arg1] [arg2…]
其中i、l、e是可选的参数:i表示执行后进入交互模式;l表示加载库文件;e表示在其后面跟lua语句进行执行,如lua –e “print(1)”
arg1、arg2是传入脚本的参数。与shell脚本执行是传入的类似。但lua使用table存储在全局变量arg中。arg1对应索引为arg[1],filename对应arg[0],而在filename之前的是负数索引。如arg[-1]=”-e”
(3)linux下apt-get install lua5.2
lua进入交互模式
(4)用LuaForWindows安装时自带安装的SciTE编辑工具编辑,并且可以执行F5
二、概述
lua脚本文件以“.lua”结尾,由lua解释器执行。一系列可执行语句称为程序块(chunk)。
Lua是可扩展、简易、高效、可移植型强的动态类型脚本语言。Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。Lua脚本可以很容易的被C/C++ 代码调用,也可以反过来调用C/C++的函数。Lua可以作为C程序的库来使用。
在程序中用“--”来注释,“--[[被注释程序块]]”来注释一段代码。
Lua语句通常不需要分号来做结尾,但加上也不会出错,而若在同一行有多条语句则加分号以区分(不加也没错,但不好看),如
a=1;b=2
在交互模式下,可以用等号开头后接表达式或变量名来打印这个表达式或常量的值——这个特性可以将Lua作为一个计算器使用。如
>=math.sin(3)
>a=30
>=a --输出a的值
三、变量类型与值
Lua是动态类型语言——动态语言是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化,其特点之一就是变量或对象的类型不需要声明,在运行时检查变量的合法性,通常不需要编译。
全局变量不需要声明,不需要注明其变量类型,并且初始化为nil(相当于空类型)。
例如变量b在先前并未声明,可以直接使用print(b),输出nil。随后可以对b赋值(赋任何类型的值)。
Lua中有8中基础类型:nil(空)、boolean(布尔)、number(数字)、string(字符串)、userdata(自定义类型)、function(函数)、thread(线程)和table(表)。函数type可以返回一个值的类型名。如
print(type(“hello”)) -->string
print(type(10*3)) -->number
print(type(print)) -->function
print(type(type(x)))-->string——不论x是什么类型,type函数返回的是一个字符串,所以这句输出string
变量甚至可以定义为函数,如
a=print -->此时a可以作为print函数使用a(“hello”)等同于print(“hello”)
1、nil
nil是用于区别值类型的一种类型。对一个全局变量赋nil值等同于删除这个全局变量。
2、boolean
boolean分为false和true,但在Lua中boolean并不是一个条件值唯一的表示方式——任何值都可以表示一个条件。Lua将值false和nil视为“假”,除此之外都是“真”———意味着数字“0”也是“真”,空字符串也是“真”。
3、number
Lua没有整数类型,用number表示实数。(用双精度实现的)
4、string
Lua中的string是不可变的值(immutablevalue),意味着不能直接在内存中修改其内容,而是会重新创建一个新的字符串。Lua的字符串和其他Lua对象(例如table或function)都是自动内存管理机制所管理的对象,这表示不需要担心字符串的分配和释放。
对一个变量赋值字面类型的string(literal string),用单引号或双引号来界定。如a=”hello”;b=’abc’ 。也可以使用转义字符“\”。特别地,Lua中用“\<ddd>”来转义一个由至多3个十进制数组成的序列,如”\97”、”\123”等。<ddd>从0-255,超过255则报错。当第一位是0时,会向后取三位,如“\0973”是“a3”。(在C中,\后的数字是八进制)
另外,还可以用“[[“与”]]“来界定一个字母字符串,保证字符串中特殊字符不被转义。如[[\n\97]]——此时不用引号来界定,输出即为\n\97,而不是换行和a。若字符串中也有[[或]]字符,则在两个方括号之间加上任意数量的等号,只有匹配到相同数量的带等号的方括号才作为一个结束。如
a=[=b[[c[i]]]=]表示的是”a=c[i]”,最外层的“[=[”,“]=]”是字符串的界定符。
Lua会对数字与字符串自动转换:在一个字符串上做算术操作时,对将字符串转换成数字。如
print(“10”+1) -->11
print(“10-1”) -->10-1
print(“hello”+1)-->错误,因为不能转换hello
另外有“..”我做字符串连接符。当在一个数字后面输入它时,必须要用一个空格来分隔,否则当成小数点,会出错。
print(10 .. 20) -->1020,(20前面可以不加空格)
print(“abc”..”de”) -->abcde
另外一些常用的字符串操作函数如下(通常是在string.下的)
①string.gsub(str,pattern,replacement,[,limitCount]) --字符串替换函数,对str中的pattern子串替换成replacement,limitCount是限定替换前面limitCount个。pattern可以使正则表达式。
print(string.gsub(“one string one”,”one”,”two”,1)) -->two string one
②string.byte(s,[i,[j]])--对s第i(和第j)个字符转换成对应的ASCII码值。i,j是可选项,默认是1——Lua中字符索引是从 1 开始,索引值也可以是负数,这种情况将被解释成向后索引,从字符串末尾开始算起。
print(string.byte(“abc”)) -->97
print(string.byte(“abc”,1,2)) -->97 98
③string.char(asc1, ...)--把一个或多个 ASCII 编码转换为对应的字符串
print(string.char(97,98,99)) -->abc
④string.find(s,pattern [, init [, plain]]) --查找目标子串,返回第一个匹配到的子串的起始位置,没有则返回nil。init指定了起始位置,plain是boolean值,表示是否启用pattern进行模式查找。
start, end= string.find("just atest", "st")
print(start, end) -->3,4(just中的3-4的范围)
⑤string.len(s) --用于返回字符串 s 的长度。还可以在字符串前加“#”来求字符串长度——“#”称为长度操作符
print(#“abc”) -->3
a=”abc” ;print(#a) -->3
⑥string.upper(s) --小写转大写,返回新字符串
⑦string.lower(s) --大写转小写
⑧string.rep(s, n [, sep]) --返回由sep作为分隔符,重复s n次的字符串,rep默认为空字符。
print(string.rep(“abc”,3)) -->abcabcabc
print(string.rep(“abc”,3,”,”)) -->abc,abc,abc
⑨string.reverse(s) --返回s的倒序字符串
⑩string.sub(s, i [, j]) -->截取s的从i到j的子串。j省略时表示到字符串末尾。i,j可以是负数,此时从s的末尾算起,从右至左为-1,-2…
print(string.sub(“abcd”,2)) -->bcd
print(string.sub(“abcd”,-3,-2)) -->bc
print( string.sub(“abcd”,-20)) -->abcd
另外还有number与string之间相互转换的函数:
①tonumber(s) --将字符串s转换成数字,若失败返回nil
②tostring(n) --将数字n转换成字符串——将数字转出字符串也可用连接符“..”
5、table
table是Lua中唯一的数据结构,称为关联数组。关联数组是类似与哈希表的,具有特殊索引方式的数组。table可以使用除了nil值以外的任何类型来索引。并且没有固定大小,可以动态地添加任意数量的元素。同一个table中元素类型可以不唯一。
用table来表示普通数组(整数作为索引的数组)、符号表、集合、记录、队列,甚至是模块、包、和对象——当调用io.read()时,表示“使用字符串‘read’作为key来索引table io”。
(1)初始化赋值
table不是普通的变量或值,而是对象。与Java类似,table是动态分配的,用引用来指向它,当没有引用指向它时,会被Lua的垃圾收集器回收(删除并复用内存)。table的创建也类似与Java对象的创建——采用构造表达式,最简单的构造表达式是{}。如
a={} --创建一个table,并用a引用它
a[“x”]=1 --print(a[“x”])输出1
a[“y”]=2 --print(a[“y”])输出2
k=1
a[k]=3 --print(a[k])或print(a[1])输出10
a[100]=10 --print(a[100])输出10
若某个索引值没有定义在table中时,输出为nil。如
print(a[“z”]) -->nil
当将某个元素赋值为nil,则删除这个元素。
(2)语法糖
对于用字符串做索引的情况,Lua有“语法糖(syntactic sugar)”来表示。
a.x=1 --等同于a[“x”]
a.y=2 --等同于a[“y”]
另外要注意区别a[x]和a[“x”],前者表示变量x的值作为索引值,后者表示字符串“x”作为索引值。
(3)table表示普通数组
当用table来表示普通数组或线性表时,需要用整数表示索引。
for i=1,10 do
a[i]=i --给a赋值1~10
end
对于数组或线性表,可以用长度操作符“#”来获取其长度(最后一个索引值)。
print(#a) -->10
当对最后一个值赋nil时,就删除该元素,#a减1。
数组的长度是一个容易模糊的问题。a={};a[100]=1;则a的长度是多少呢?
用#a获得是0,因为Lua数组索引从1开始算起,将nil作为界定数组结尾的标志。a数组a[1]=nil,所以#a是0。因为数组a从1到100中间没有连续的有效值。前面用#a等到10是因为其连续没有空隙(Hole)。可以用table.maxn(tablename)来获取一个最大正索引数。table.maxn(a)返回100。
故对于b={};b[0]=1;#b等于0,table.maxn(b)也是0.