本日笔记: Lua与其他程序语言语法不同之处
变量无需声明类型(variable type), 无需在首次使用前声明
以下语句是用C语言书写的.
int i;
i = 9;
printf("%d/n",i);
类似的行为在Lua中的语句是这样的:
> i = 9
> print(i)
9
不需要事先声明i及其类型, 可以直接使用
此外, 变量的类型也不是固定的, 是由其当前值决定的. 可以随时赋不同类型的值给同一个变量.
> i = 9
> print(i)
9
> i = "Hello Azeroth!"
> print(i)
Hello Azeroth!
不过, 虽然使用时不需要指明, 但变量类型是存在的, 包括: number, string, Boolean, function, table, nil, thread, userdata
可以通过type语句取得类型, 如:
> print(type("Hello Azeroth!"))
string
支持为多个变量同时赋值
可使用以下的方法, 一一对应赋值:
> x, y = 3, 5
> print(x * y)
15
[ 非的逻辑运算符是~而非! ]
> print(1 ~= 3)
true
^ 运算符为幂运算而非异或运算
即:
> print(13^2)
将得到169.
字符串的操作
可以很方便地使用tostring() / tonumber()函数进行字符串与数字类型的转换, 支持科学记数法.
> x = tonumber("1e3")
> print(x)
1000
提供运算符 ".." 用于连接字符串, 如:
> x = "a" .. "b"
> print(x)
ab
Lua除支持双引号("")表示字符串外, 也支持用单引号('')或方括号([[]]), 以应付不同的场合, 特别是当字符串中包含有", ', ]时:
> x = 'Hello'
> print(x)
Hello
> x = 'Isn't it nice?'
stdin:1: '=' expected near 'it'
此句出错; Lua认为字符串是'Isn', 从而无法解读后面的部分; 一种解法是使用转义符. Lua和其他语言一样支持转义符:
> x = 'Isn/'t it nice?'
> print(x)
Isn't it nice?
或使用方括号:
> x = [[This is a long string including ' and "]]
> print(x)
This is a long stirng including ' and "
方括号的配对规则是: [==..=[ 字符串内容 ]==..=], 在[ [之间可以没有等号(上面的情形), 或者有任意数量的等号, 配对时将寻找包含相同数量等号的] ]. 例如, 可以用下面的方式在字符串中包含]]:
> x = [==[This is a long string including ', ]] and "]==]
> print(x)
This is a long string including ', ]] and "
方括号还支援多行字符串。
字符串长度的取法和C Shell取Table长度类似, 使用"#"运算符:
> print(#"Hello")
5
或者用函数string.len():
> x = "Hello"
> print(string.len(x))
5
逻辑运算的特殊现象
看这个语句:
> print(true and 4)
4
这个结果有别于其他语言, 比如C或者C++; 后者在同样的情况下会输出true(因为非0值都被当作真处理).
先来看这个问题: 在普通的逻辑表达式A and B中, 明显的, 如果第一个, 也就是A为真, 那么表达式的值是由B决定的; 即是说, A and B, 若A为真, 那么B真则表达式A and B为真, B假则表达式A and B为假.
所以Lua做出这样处理的依据是: true and 4是一个逻辑与(A and B)的表达式, 由于第一个的值为真, 表达式的值是其实是由第二个决定的; 换言之, 只要直接返回第二个表达式的值就行了. Lua的推广是, 第二个表达式即使不产生true或false的布尔值, 也可以被返回.
利用这样的运算特性, 可以在Lua内达到C/C++中a ? b : c语句的效果:
> print(true and "Hello" or "Azeroth!")
Hello
> print(false and "Hello" or "Azeroth!")
Azeroth
换言之, C/C++中的"a ? b : c"语句在Lua中可以写为a and b or c.
但是这个写法是有缺陷的. 在a and b or c中, 通常a是逻辑表达式, b和c不会是表达式, 首先运算a and b, 然后是(a and b) or c. 正常情况下, 若a为真, a and b会返回b, 如果b是一个字串或数值, 它就是'真', 因此b or c会直接返回b, 符合预期的"a为真, 返回b"的设计.
但如果b是一个变量, 而该变量恰好为空(如尚未定义)时, b为假, b or c就会返回c. 此时产生了"a为真, 但返回c"的情况.
因此为了使表达式a and b or c正常工作, 必须保证b为真. 在不能保证b为真的情况下, 只有用if-else语句才能保证逻辑严密性.
(参考: 有关lua中"(a and b) or c"与C中"a?b:c"等同的条件, by carl2500 from CWDG)
变量的作用范围
在Lua中可以手动划分代码块, 使用的是do-end语句:
> do
>> local i = 10
>> print(i)
>> end
10
> print(i)
nil
和其它的程序语言使用{ }的区别不大.