string 转数字
- n=tonumber(s);
逻辑运算
逻辑运算符认为 false 和 nil 是假(false),其他为真,0 也是 true.
and or not
and 和 or 的运算结果不是 true 和 false,而是和它的两个操作数相关。
and 的优先级比 or 高。
a and b -- 如果 a 为 false,则返回 a,否则返回 b
a or b -- 如果 a 为 true,则返回 a,否则返回 b
一个很实用的技巧:如果 x 为 false 或者 nil 则给 x 赋初始值 v
x = x or v
等价于
if not x then
x = v
end
C 语言中的三元运算符
a ? b : c
在 Lua 中可以这样实现:
(a and b) or c
not 的结果一直返回 false 或者 true
表的构造
- 最简单的构造函数是{},用来创建空表
days = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"}
Lua 将"Sunday"初始化 days[1](第一个元素索引为 1),用"Monday"初始化 days[2]...
print(days[4]) --> Wednesday
构造函数可以使用任何表达式初始化:
tab = {sin(1), sin(2), sin(3), sin(4),
sin(5),sin(6), sin(7), sin(8)}
如果想初始化一个表作为 record 使用可以这样:
a = {x=0, y=0} <--> a = {}; a.x=0; a.y=0
- 不管用何种方式创建 table,我们都可以向表中添加或者删除任何类型的域,构造函数仅仅影响表的初始化。
w = {x=0, y=0, label="console"}
x = {sin(0), sin(1), sin(2)}
w[1] = "another field"
x.f = w
print(w["x"]) --> 0
print(w[1]) --> another field
print(x.f[1]) --> another field
w.x = nil -- remove field "x"
- 每次调用构造函数,Lua 都会创建一个新的 table,可以使用 table 构造一个 list:
list = nil
for line in io.lines() do
list = {next=list, value=line}
end
这段代码从标准输入读进每行,然后反序形成链表。下面的代码打印链表的内容:
l = list
while l do
print(l.value)
l = l.next
end
- 在同一个构造函数中可以混合列表风格和 record 风格进行初始化,如
polyline = {color="blue", thickness=2, npoints=4,
{x=0, y=0},
{x=-10, y=0},
{x=-10, y=1},
{x=0, y=1}
}
这个例子也表明我们可以嵌套构造函数来表示复杂的数据结构.
print(polyline[2].x) --> -10
- 上面两种构造函数的初始化方式还有限制,比如你不能使用负索引初始化一个表中
元素,字符串索引也不能被恰当的表示。下面介绍一种更一般的初始化方式,我们用
[expression]显示的表示将被初始化的索引:
opnames = {["+"] = "add", ["-"] = "sub",
["*"] = "mul", ["/"] = "div"}
Programming in Lua 17
Copyright ® 2005, Translation Team, www.luachina.net
i = 20; s = "-"
a = {[i+0] = s, [i+1] = s..s, [i+2] = s..s..s}
print(opnames[s]) --> sub
print(a[22]) --> ---
-
在构造函数的最后的","是可选的,可以方便以后的扩展。
a = {[1]="red", [2]="green", [3]="blue",}
-
在构造函数中域分隔符逗号(",")可以用分号(";")替代,通常我们使用分号用来 分割不同类型的表元素。
{x=10, y=45; “one”, “two”, “three”}
基本语法
赋值语句
-
Lua 可以对多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语
句右边的值会依次赋给左边的变量。
a, b = 10, 2x <–> a=10; b=2x -
双向赋值,交换变量,少的补nil,多的忽略
-
x, y = y, x -- swap 'x' for 'y' a[i], a[j] = a[j], a[i] -- swap 'a[i]' for 'a[i]' a,b,c=0,1 --> c为nil a,b=1,2,3 -->3忽略
-
将函数调用返回给变量:
a, b = f()
f()返回两个值,第一个赋给 a,第二个赋给 b。
-
局部变量
- local修饰局部变量,局部变量只在被声明的代码块有效
- 应该尽可能的使用局部变量,有两个好处:
- 避免命名冲突
- 访问局部变量的速度比全局变量更快.
- 我们给 block 划定一个明确的界限:do…end 内的部分。当你想更好的控制局部变量的作用范围的时候这是很有用的
do
local a2 = 2*a
local d = sqrt(b^2 - 4*a*c)
x1 = (-b + d)/a2
x2 = (-b - d)/a2
end -- scope of 'a2' and 'd' ends here
print(x1, x2)
控制结构语句
-
if三种形式
-
if conditions then then-part end;
-
if conditions then then-part else else-part end;
-
```c if conditions then then-part elseif conditons then elseif-part else else-part end; ```
-
-
while语句
while condition do statements; end
-
repeat-until 语句
重复执行,直到until内条件不成立时截至。a = 10 --[ 执行循环 --] repeat print("a的值为:", a) a = a + 1 until( a > 15 )
-
for语句两大类
-
数值for循环
for var=exp1,exp2,exp3 do loop-part end exp3作为step从exp1(初始值)到exp2(终止值),exp3可省略,默认为1
-
- 三个表达式只会被计算一次,并且是在循环开始前
for i=1,f(x) do // f(x)只会在循环前被调用一次。 print(i) end for i=10,1,-1 do print(i) end
- break退出循环
-
-
范型 for 循环:
- 遍历数组a的value
// print all values of array 'a' for i,v in ipairs(a) do print(v) end
- 遍历数组a的key
for k in ipairs(a) do print(k) end
-
再看一个例子,假定有一个表:
days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
现在想把对应的名字转换成星期几,一个有效地解决问题的方式是构造一个反向表:
revDays = {["Sunday"] = 1, ["Monday"] = 2, ["Tuesday"] = 3, ["Wednesday"] = 4, ["Thursday"] = 5, ["Friday"] = 6, ["Saturday"] = 7}
下面就可以很容易获取问题的答案了:
x = “Tuesday”
print(revDays[x]) --> 3 -
我们不需要手工,可以自动构造反向表
revDays = {} for i,v in ipairs(days) do revDays[v] = i end
-
-
break和return
-Lua 语法要求 break 和 return 只能出现在 block 的结尾一句(也就是说:作为 chunk的最后一句,或者在 end 之前,或者 else 前,或者 until 前),
例如:local i = 1 while a[i] do if a[i] == v then break end i = i + 1 end
函数
-
语法
function func_name (arguments-list) statements-list; end;
- 当函数只有一个参数并且这个参数是字符串或者表构造的时候,()是可选的:
print "Hello World" <--> print("Hello World") dofile 'a.lua' <--> dofile ('a.lua') print [[a multi-line message]] <--> print([[a multi-line message]]) f{x=10, y=20} <--> f({x=10, y=20}) type{} <--> type({})
- Lua 也提供了面向对象方式调用函数的语法,比如 o:foo(x)与 o.foo(o, x)是等价的
- Lua 函数实参和形参的匹配与赋值语句类似,多余部分被忽略,缺少部分用 nil 补足。