《programming in lua》第二版第 1-2 章。
运行环境
这里使用的 lua 版本是 5.1.4,操作系统是 debian 6.0,
到 lua 的官网下载源码包,因为是 ANSI C 写成的解析器,所以在各个平台上编译都很方便。编译之后会在源码目录里的 src 下生成两个可执行文件:lua 和 luac,其中 lua 用来解析脚本,luac 用来把脚本编译成二进制文件。在源码包里也带有一些例子,在 test 目录下。例如可以用下面的命令来运行 test 下的例子(假设当前目录为解压后的源码根目录):
./src/lua test/hello.lua
或者使用 luac 把脚本转换成二进制文件:
./src/luac test/hello.lua
默认的输出文件是 luac.out。接着可以使用 lua 来运行这个二进制文件:
./src/lua luac.out
得到的结果和直接运行脚本的结果一样,不过二进制文件的速度要快些。还有一种方法是直接执行 lua 语句:
lua -e "print(\"Hello, world.\")"
第一个 lua 程序
print("Hello, world!")
一个 lua 脚本或者在交互模式下的一行代码叫做块(chunk),块与块之间可以通过行来分隔,也可以通过分号来分隔,甚至写在同一行上的两条语句可以仅使用空格分隔。
变量命名规则和 c 差不多,都是数字,字母,下划线的组合,并且第一个字符不能是数字。保留的关键字有下面这些:
and break do else elseif
end false for function if
in local nil not or
repeat return then true until
while
单行注释使用两个连字符开头;多行注释看着有点奇怪:
-- the first program in lua
--[[
multiline comment
--]]
print("Hello, world.")
可以通过命令行向 lua 脚本传递参数。在 lua 脚本中有一个 arg 数组保存传递进来的参数。例如执行下面的命令:
lua script a b
arg 数组的各个值如下:
arg[-1] = lua
arg[0] = script
arg[1] = a
arg[2] = b
类型
lua 是一种动态类型的语言,变量在使用前不需要声明,初始值为 nil。在 lua 中变量是没有类型的,只有变量中保存的值才有类型。lua 中有 8 种基本类型:nil,boolean,number,string,userdata,function,thread,table。通过 type() 函数可以获取变量当前保存的值的类型:
print(type(a)) -- nil
a = 10
print(type(a)) -- number
a = "abc"
print(type(a)) -- string
a = print
print(type(a)) -- function
print(type(type(a))) -- string
无论 a 是什么类型,最后的语句总是输出“string”,因为 type() 的返回值是 string 类型。
boolean 只有两种取值:true 和 false。除了 nil 和 false 的值为 false 之外,其它的值均为 true(0 和空字符串也为真,这点与 c 不一样)。
number 类型代表所有实数,不区分整型和浮点型(单精度或双精度)。number 型也可以采用科学计数法,如 2.5e12 等。
string 类型可以使用单引号或双引号来界定,如果字符串中有相同的引号可以使用反斜杠转义(例如“a = “abc\”d””这样的),或者使用不同于字符串内引号的另一种引号(例如“a = ‘abc”d’”或者“a = “abc’d””)。lua 也有类似 c 中的一些特殊转义字符,如换行“\n”,制表“\t”等。如果反斜杠后跟数值表示某个字符的 ascii 值,例如“print(“\99”)”会打印字符“c”。要使用多行字符串的话可以使用符号“[[”和“]]”,就像使用多行注释一样:
multilines = [[
<html>
<title>page</title>
<body>hello</body>
</html>
]]
print(multilines)
但是如果字符串中含有“a[b[c]]”这样包含“]]”的字符串的话上面的方法就不起作用了。从 5.1 版本起,lua 支持在第一个“[[”的两个“[”之间添加若干个“=”作为起始标志,两个“]”之间拥有相同数量的“=”的“]]”作为对应的结束标志,像下面这样:
multilines = [=[
a[b[c]]
]=]
print(multilines)
“[[”和“]]”之间的“=”可以为任意数量,但数量一定要相等。同样的语法也可以用在注释中(即在“–[[”的两个“[”中添加“=”,同样结束的位置“–]]”的两个“]”中也要有相同数量的“=”)。
lua 提供了 string 到 number 的自动转换,例如“print(“10” + 1)”输出“11”,但是“print(“hello” + 1)”会报错,原因是不能将字符串“hello”转换成数值。字符串连接符“..”可以把数值转换成字符串,例如“print(10 .. 20)”会输出“1020”(注意“..”两边有空格)。总的来说,上面这些隐式转换都不是好习惯,如果要进行转换最好使用函数显式转换,例如转换成数值可以使用函数 tonumber(),转换成 string 可以使用 tostring() 等。
在 lua5.1 之后可以使用“#”来获取 string 的长度,例如“print(#”hello”)”的输出是“5”。
table 是 lua 中唯一的数据结构,是一种关联数组,而且 table 中的 key 可以是不同的类型:
a = {} -- create a table and store its reference in 'a'
a["x"] = 10
print(a["x"]) -- 10
a[20] = "k"
print(a[20]) -- k
变量 a 只是保存对 table 的一个引用,如果把 a 赋值给另一个变量 b,那么 a 和 b 指向的是同一个 table:
a = {} -- create a table and store its reference in 'a'
a["x"] = 10
b = a
print(b["x"]) -- 10
b["x"] = 5
print(a["x"]) -- 5
通过把 nil 赋给变量可以删除一个变量所指向的内容,lua 的 garbage collector 会将无用的内存收集起来重新投入使用。
另外一种访问 table 元素的方法有点像访问结构体成员的“.”操作符,也即“a.key”相当于“a[“key”]”:
y = "x"
a.y = 10 -- a["x"] = 10
print(a.x) -- print(a["x"])
print(a.y) -- nil
“.”后面的是 key 而不是指向 key 的变量的名称。
function 可以作为参数传递,也可以作为返回值。
userdata 是用户自定义的 c 语言数据类型,可以存储在 lua 变量中,lua 中只定义了赋值和判断是否相等两种操作。
用撸啊干什么活儿啊???
学着玩的…
魔兽插件用的就是这个语言…求写插件