《programming in lua》(1)

《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程序

1
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

单行注释使用两个连字符开头;多行注释看着有点奇怪:

1
2
3
4
5
6
7
-- 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()函数可以获取变量当前保存的值的类型:

1
2
3
4
5
6
7
8
9
10
11
12
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”。要使用多行字符串的话可以使用符号”[["和"]]”,就像使用多行注释一样:

1
2
3
4
5
6
7
8
multilines = [[
<html>
<title>page</title>
<body>hello</body>
</html>
]]
 
print(multilines)

但是如果字符串中含有”a[b[c]]”这样包含”]]”的字符串的话上面的方法就不起作用了。从5.1版本起,lua支持在第一个”[["的两个"["之间添加若干个"="作为起始标志,两个"]“之间拥有相同数量的”=”的”]]”作为对应的结束标志,像下面这样:

1
2
3
4
5
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可以是不同的类型:

1
2
3
4
5
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:

1
2
3
4
5
6
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"]:

1
2
3
4
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中只定义了赋值和判断是否相等两种操作。

你可能感兴趣的:(《programming in lua》(1))