第03章 表达式
表达式是有量(变量或常量)与运算符(显示或隐式)组成的语句。
算数操作符
Lua 的算术操作符有如右几个:+ - * / ^ %
都用于实数计算,有几个和 Java 中有些区别,单独介绍如下:
^
乘方,如x^0.5
,x^2
分别是开根号和平方%
的定义:a%b == a - floor(a/b)*b
,因为它的运算范围也是实数域,所以有些奇怪的表现,比如x%1
得到了x
的小数部分,x-x%1
得到了x
的整数部分,x - x%0.001
表示x
截取到小数位后第三位(没有四舍五入)。
另外,-
也可以是一元操作符的负号。
关系操作符
Lua 的关系操作符有如右几个: < > <= >= == ~=
,有几点需要注意的:
~=
不等号,注意,不能用 C 的!=
- 大小性的比较,只能是两个数字或者两个字串来做,即数字只能和数字做比较,字串只能和字串做比较,如果把数字和字串做比较,程序会出错。字串比较是按字母次序来比较的,如:
print("a" < "b") --> true
逻辑操作符
Lua 的逻辑操作符有三个:and or not
Lua 的逻辑运算认为只有 false
和 nil
是假(false
),其他为真,0也是 true
. 不知道 C 中是具体返回操作量的值,还是返回 true/false? 貌似 C 中对 true /false 的规定和 Lua 有些差别,待查 TODO。
or 和 and 运算的返回值,这可能是 lua 相对其他语言,比较变态的地方,它并不限定返回逻辑值 true/false
,而是返回操作量的值(这点和 Java 很不一样,Java 的习惯是,只返回 true/false
),具体规定如下:
a and b
-- 如果 a 为false
,则返回 a,否则返回 b。这其实是短路运算的结果,如果 a 为false
,因为是and
运算,肯定表达式的值就是a,否则,就是ba or b
-- 如果 a 为true
,则返回 a,否则返回 b。这也是短路运算的结果。or
,and
都使用 short-cut evaluation(短路求值)
书上说 (a and b) or c
等价于 C 中的 a ? b : c
,可实际情况并非完全如此,如:
a, b, c = true, false, 0909
print((a and b) or c)
将输出909, 即 c 的值——在 a 为 true
时,输出的不是 b 的值。只有在 b ~= false
时, (a and b) or c
才等价于 C 中的 a ? b : c
,此时可以如此解释:如果 a 为 true
,值决定于 b,如果 a 为 false
,值决定于 c。
not
运算符只返回 true/false
不同语言中的逻辑运算可以专门记录一下:TODO《C, Lua, Java, JavaScript 中的逻辑运算比较》
字符串连接
Lua 的字符串连接使用双点号 .. ,这个和 Java 中使用 + 也是不一样的。具体在使用上,要注意:
- 不要把数字和字串来做连接,也不要把 nil 和字串去做连接,最好把需要连接的量显示转为 string 再操作。
- 双点号的左右应该各有一个空格,美观,而且,左边要是没空格,会被误认为是小数点,引起报错。
TODO 列举几个实例
TODO 比较一些不同语言的字符串连接:Java: +, C: ?, JavaScript: +, Oracle SQL: ||, Python: ?, Linux shell: ?
运算符的优先级
虽然运算符有优先级的规定,但建议多用括号,以明确含义,增强程序的可读性和可维护性。
or
and
< > <= >= ~= ==
..
+ -
* / %
not # - (unary)
^
(运算优先级,从上往下逐渐增高)
table constructor
(这部分内容,暂时整理到本系列的《第二章 类型和值》里去了,将来再重新整理。TODO)