Lua 的语法比较简单,学习h也比较省力,但功能却q不弱?/p>
在Lua中,一切都是变量,除了关键字。请Cq句话?/p>
I. 首先是注?/strong>
写一个程序,L不了注释的?br /> 在Lua中,你可以用单行注释和多行注释?br /> 单行注释中,q箋两个减号"--"表示注释的开始,一直gl到行末为止。相当于C++语言中的"http://"?br /> 多行注释中,?--[["表示注释开始,q且一直gl到"]]"为止。这U注释相当于C语言中的"/*…*/"。在注释当中Q?[["?]]"是可以嵌套的?/p>
II. Lua~程
l典?Hello world"的程序L被用来开始介l一U语a。在Lua中,写一个这LE序很简单:
print("Hello world")
在Lua中,语句之间可以用分?Q?隔开Q也可以用空白隔开。一般来_如果多个语句写在同一行的话,L用分号隔开?br /> Lua 有好几种E序控制语句Q如Q?/p>
条g控制Qif 条g then … elseif 条g then … else … end
While循环Qwhile 条g do … end
Repeat循环Qrepeat … until 条g
For循环Qfor 变量 = 初|l点|步进 do … end
For循环Qfor 变量1Q变?Q?#8230; Q变量N in表或枚D函数 do … end
注意一下,for的@环变量L只作用于for的局部变量,你也可以省略步进|q时候,for循环会?作ؓ步进倹{?br /> 你可以用break来中止一个@环?br /> 如果你有E序设计的基Q比如你学过BasicQC之类的,你会觉得Lua也不难。但Lua有几个地Ҏ明显不同于这些程序设计语a的,所以请特别注意?/p>
Q语句块
语句块在C++中是?{"?}"括v来的Q在Lua中,它是用do ?end 括v来的。比如:
do print("Hello") end
你可以在 函数 中和 语句?中定局部变量?/p>
Q赋D?br /> 赋D句在Lua被强化了。它可以同时l多个变量赋倹{?br /> 例如Q?br /> a,b,c,d=1,2,3,4
甚至是:
a,b=b,a -- 多么方便的交换变量功能啊?br /> 在默认情况下Q变量L认ؓ是全局的。假如你要定义局部变量,则在W一ơ赋值的时候,需要用local说明。比如:
local a,b,c = 1,2,3 -- a,b,c都是局部变?/p>
Q数D?br /> 和C语言一P支持 +, -, *, /。但Luaq多了一?^"。这表示指数乘方q算。比?^3 l果?, 2^4l果?6?br /> q接两个字符Ԍ可以?.."q处W。如Q?br /> "This a " .. "string." -- {于 "this a string"
Q比较运?br /> < > <= >= == ~=
分别表示 于Q大于,不大于,不小于,相等Q不相等
所有这些操作符Lq回true或false?br /> 对于TableQFunction和Userdatacd的数据,只有 == ?~=可以用。相{表CZ个变量引用的是同一个数据。比如:
a={1,2}
b=a
print(a==b, a~=b) -- true, false
a={1,2}
b={1,2}
print(a==b, a~=b) -- false, true
Q逻辑q算
and, or, not
其中Qand ?or 与C语言区别特别大?br /> 在这里,请先CQ在Lua中,只有false和nil才计ؓfalseQ其它Q何数据都计算为trueQ?也是trueQ?br /> and ?or的运结果不是true和falseQ而是和它的两个操作数相关?br /> a and bQ如果a为falseQ则q回aQ否则返回b
a or bQ如?a 为trueQ则q回aQ否则返回b
丑և个例子:
print(4 and 5) --> 5
print(nil and 13) --> nil
print(false and 13) --> false
print(4 or 5) --> 4
print(false or 5) --> 5
在Lua中这是很有用的特性,也是比较令hh的特性?br /> 我们可以模拟C语言中的语句Qx = a? b : cQ在Lua中,可以写成Qx = a and b or c?br /> 最有用的语句是Q?x = x or vQ它相当于:if not x then x = v end ?/p>
Q运符优先U,从高C序如下Q?br /> ^
not - Q一元运)
* /
+ -
..Q字W串q接Q?br /> < > <= >= ~= ==
and
or
III. 关键?/strong> 关键字是不能做ؓ变量的。Lua的关键字不多Q就以下几个Q?br /> and break do else elseif IV. 变量cd 怎么定一个变量是什么类型的呢?大家可以用type()函数来检查。Lua支持的类型有以下几种Q?/p> Nil I|所有没有用过的变量,都是nil。nil既是|又是cd?br /> Boolean 布尔?br /> Number 数|在Lua里,数值相当于C语言的double V. 变量的定?/strong> 所有的语言Q都要用到变量。在Lua中,不管你在什么地方用变量,都不需要声明,q且所有的q些变量L全局变量Q除非,你在前面加上"local"?br /> q一点要特别注意Q因Z可能惛_函数里用局部变量,却忘了用local来说明?br /> 至于变量名字Q它是大写相关的。也是_A和a是两个不同的变量?br /> 定义一个变量的Ҏ是赋倹{?Q?操作是用来赋值的 B. Boolean C. Number D. String ׃q种字符串只能写在一行中Q因此,不可避免的要用到转义字符。加入了转义字符的串Q看h实在是不敢恭l_比如Q?br /> "one line\nnext line\n\"in quotes\", 'in quotes'" 值得注意的是Q在q种字符串中Q如果含有单独用的"[["?]]"׃然得?\["?\]"来避免歧义。当Ӟq种情况是极会发生的?/p> |
E. Table
关系表类型,q是一个很强大的类型。我们可以把q个cd看作是一个数l。只是C语言的数l,只能用正整数来作索引Q在Lua中,你可以用Lcd来作数组的烦引,除了nil。同P在C语言中,数组的内容只允许一U类型;在Lua中,你也可以用Q意类型的值来作数l的内容Q除了nil?br /> Table的定义很单,它的主要特征是用"{"?}"来括起一pd数据元素的。比如:
T1 = {} -- 定义一个空?br /> T1[1]=10 -- 然后我们可以象C语言一h使用它了?br /> T1["John"]={Age=27, Gender="Male"}
q一句相当于Q?br /> T1["John"]={} -- 必须先定义成一个表Q还记得未定义的变量是nilcd?br /> T1["John"]["Age"]=27
T1["John"]["Gender"]="Male"
当表的烦引是字符串的时候,我们可以写成Q?br /> T1.John={}
T1.John.Age=27
T1.John.Gender="Male"
?br /> T1.John{Age=27, Gender="Male"}
q是一个很强的Ҏ?/p>
在定义表的时候,我们可以把所有的数据内容一起写?{"?}"之间Q这样子是非常方便,而且很好看。比如,前面的T1的定义,我们可以q么写:
T1=
{
10, -- 相当?[1] = 10
[100] = 40,
John= -- 如果你原意,你还可以写成Q["John"] =
{
Age=27, -- 如果你原意,你还可以写成Q["Age"] =27
Gender=Male -- 如果你原意,你还可以写成Q["Gender"] =Male
},
20 -- 相当?[2] = 20
}
看v来很漂亮Q不是吗Q我们在写的时候,需要注意三点:
W一Q所有元素之_L用逗号"Q?隔开Q?br /> W二Q所有烦引值都需要用"["?]"括v来;如果是字W串Q还可以L引号和中括号Q?br /> W三Q如果不写烦引,则烦引就会被认ؓ是数字,q按序自动?往后编Q?/p>
表类型的构造是如此的方便,以致于常常被人用来代曉K|文件。是的,不用怀疑,它比ini文g要漂亮,q且强大的多?/p>
F. Function
函数Q在Lua中,函数的定义也很简单。典型的定义如下Q?br /> function add(a,b) -- add 是函数名字,a和b是参数名?br /> return a+b -- return 用来q回函数的运行结?br /> end
h意,return语言一定要写在end之前。假如你非要在中间放上一句returnQ那么请写成Qdo return end?br /> q记得前面说q,函数也是变量cd吗?上面的函数定义,其实相当于:
add = function (a,b) return a+b end
当你重新ladd赋值时Q它׃再表C个函C。你甚至可以赋给addL数据Q包括nil Q这P你就清除了add变量Q。Function是不是很象C语言的函数指针呢Q?/p>
和C语言一PLua的函数可以接受可变参C敎ͼ它同h?…"来定义的Q比如:
function sum (a,b,…)
如果惛_?#8230;所代表的参敎ͼ可以在函C讉Karg局部变量(表类型)得到?br /> ?sum(1,2,3,4)
则,在函CQa = 1, b = 2, arg = {3, 4}
更可늚是,它可以同时返回多个结果,比如Q?br /> function s()
return 1,2,3,4
end
a,b,c,d = s() -- 此时Qa = 1, b = 2, c = 3, d = 4
前面说过Q表cd可以拥有Lcd的|包括函数Q因此,有一个很强大的特性是Q拥有函数的表,哦,我想更恰当的应该说是对象吧。Lua可以使用面向对象~程了。不信?那我举例如下Q?/p>
t =
{
Age = 27
add = function(self, n) self.Age = self.Age+n end
}
print(t.Age) -- 27
t.add(t, 10)
print(t.Age) -- 37
不过Qt.add(t,10) q一句实在是有点土对吧?没关p,在Lua中,你可以简写成Q?br /> t:add(10) -- 相当?t.add(t,10)
G. Userdata ?Thread
q两个类型的话题Q超Z本文的内容,׃打算l说了?/p>===========================================================
VI. l束?/strong>
p么结束了吗?当然不是Q接下来Q需要用Lua解释器,来帮助你理解和实践了。这小文只是帮助你大体了解Lua的语法。如果你有编E基Q相信会很快对Lua上手了?br /> pC语言一PLua提供了相当多的标准函数来增强语言的功能。用这些标准函敎ͼ你可以很方便的操作各U数据类型,q处理输入输出。有兌斚w的信息,你可以参考《Programming in Lua 》一书,你可以在|络上直接观看电子版Q网址为:http://www.lua.org/pil/index.html
当然QLua的最强大的功能是能与宿主E序亲蜜无间的合作,因此Q下一文章,我会告诉大家Q如何在你的E序中用Lua语言作ؓ脚本Q你的E序和Lua脚本q行交互?/p>
使用程
1. 函数的?/strong>
以下E序演示了如何在Lua中用函? 及局部变?br />例e02.lua
-- functions
function pythagorean(a, b)
local c2 = a^2 + b^2
return sqrt(c2)
end
print(pythagorean(3,4))
q行l果
5
E序说明
在Lua中函数的定义格式?
function 函数?参数)
...
end
与Pascal语言不同, end不需要与begin配对, 只需要在函数l束后打个end可以了.本例函数的作用是已知直角三角形直角边, 求斜辚w? 参数a,b分别表示直角辚w,
在函数内定义了local形变量用于存储斜边的qx. 与C语言相同, 定义在函数内的代码不会被直接执行, 只有ȝ序调用时才会被执?
local表示定义一个局部变? 如果不加local刚表Cc2Z个全局变量, local的作用域是在最里层的end和其配对的关键字之间, 如if ... end, while ... end{。全局变量的作用域是整个程序?/p>
2. 循环语句
例e03.lua
-- Loops
for i=1,5 do
print("i is now " .. i)
end
q行l果
i is now 1
i is now 2
i is now 3
i is now 4
i is now 5
E序说明
q里偶们用到了for语句
for 变量 = 参数1, 参数2, 参数3 do
循环?br />end
变量以参数3为步? 由参?变化到参?
例如:
for i=1,f(x) do print(i) end
for i=10,1,-1 do print(i) end
q里print("i is now " .. i)中,偶们用到?.Q这是用来连接两个字W串的,偶在(1)的试试看中提到的Q不知道你们{对了没有。虽然这里i是一个整型量QLua在处理的时候会自动转成字符串型Q不需偶们费心?/p>
3. 条g分支语句
例e04.lua
-- Loops and conditionals
for i=1,5 do
print(“i is now “ .. i)
if i < 2 then
print(“small”)
elseif i < 4 then
print(“medium”)
else
print(“big”)
end
end
q行l果
i is now 1
small
i is now 2
medium
i is now 3
medium
i is now 4
big
i is now 5
big
E序说明
if else用法比较? cM于C语言, 不过此处需要注意的是整个if只需要一个end,哪怕用了多个elseif, 也是一个end.
例如
if op == "+" then
r = a + b
elseif op == "-" then
r = a - b
elseif op == "*" then
r = a*b
elseif op == "/" then
r = a/b
else
error("invalid operation")
end
4.试试?/strong>
Lua中除了for循环以外, q支持多U@? Lwhile...do和repeat...until改写本文中的forE序?br />
数组的?/strong>
1.?/strong>
Lua语言只有一U基本数据结? 那就是table, 所有其他数据结构如数组?cd, 都可以由table实现.
2.table的下?/strong>
例e05.lua
-- Arrays
myData = {}
myData[0] = “foo”
myData[1] = 42
-- Hash tables
myData[“bar”] = “baz”
-- Iterate through the
-- structure
for key, value in myData do
print(key .. “=“ .. value)
end
输出l果
0=foo
1=42
bar=baz
E序说明
首先定义了一个table myData={}, 然后用数字作Z标赋了两个值给? q种定义ҎcM于C中的数组, 但与数组不同的是, 每个数组元素不需要ؓ相同cd,像本例中一个ؓ整型, 一个ؓ字符?
E序W二部分, 以字W串做ؓ下标, 又向table内增加了一个元? q种table非常像STL里面的map. table下标可以为Lua所支持的Q意基本类? 除了nilg?
Lua对Table占用内存的处理是自动? 如下面这D代?br />a = {}
a["x"] = 10
b = a -- `b' refers to the same table as `a'
print(b["x"]) --> 10
b["x"] = 20
print(a["x"]) --> 20
a = nil -- now only `b' still refers to the table
b = nil -- now there are no references left to the table
b和a都指向相同的table, 只占用一块内? 当执行到a = nil? b仍然指向table,
而当执行到b=nil? 因ؓ没有指向table的变量了, 所以Lua会自动释放table所占内?/p>
3.Table的嵌?/strong>
Table的用还可以嵌套Q如下例
例e06.lua
-- Table ‘constructor’
myPolygon = {
color=“blue”,
thickness=2,
npoints=4;
{x=0, y=0},
{x=-10, y=0},
{x=-5, y=4},
{x=0, y=4}
}
-- Print the color
print(myPolygon[“color”])
-- Print it again using dot
-- notation
print(myPolygon.color)
-- The points are accessible
-- in myPolygon[1] to myPolygon[4]
-- Print the second point’s x
-- coordinate
print(myPolygon[2].x)
E序说明
首先建立一个table, 与上一例不同的是,在table的constructor里面有{x=0,y=0}, q是什么意思呢Q?q其实就是一个小table, 定义在了大table之内, table的table名省略了.最后一行myPolygon[2].xQ就是大table里面table的访问方?