C/C++ 系语言中有条件运算符(?:
),表达式 a ? b : c
在 a 为真时返回 b,在 a 为假返回 c。
尽管这看起来像是 if ... else ...
的语法糖,但是在 LUA 中却没有这样的条件运算符,所以在 LUA 中需要像下面这样写:
local x
if a then
x = a
else
x = b
end
,这无疑看起来特别麻烦,不够简洁。于是我们就经常用 LUA 中的逻辑运算符来模拟前面的条件运算符。
对于逻辑运算符 and,如果它的第一个操作数为真,那么返回第二个操作数,否则返回第一个操作数;
对于逻辑运算符 or,如果它的第一个操作数为真,那么返回第一个操作数,否则返回第二个操作数。
(由于 LUA 是动态类型语言,所以逻辑运算符返回的是操作数的值,而不是代表运算结果的逻辑真与假值。)
于是很多时候,我们会采用 (a and b) or c
的形式来模仿条件运算符的功能。由于 and 的优先级高于 or,
所以可以简写成 a and b or c
。
但是上面的写法如果要和条件表达式的作用类似的话,需要一个前提:b 不为假。因为它其实是两个表达式的合并,需要遵循两个运算符的规则求值。
当 a 为假,a and b
返回 a(假),然后 a or c
返回 c,这条规则满足条件运算符在 a 为假时的求值。
但当 a 为真时,a and b
返回 b(未知),然后进行 b or c
的求值。如果 b 为真,返回 b,否则返回 c。
也就是说:当条件 a 为真时,同时需要 b 也为真,这个表达式才可以当作条件运算符来使用。这一点很重要,否则就会掉坑。
在 LUA 中,除 false
和 nil
外,其它所有类型的值都为真。如果能够确保 b 不是假,则可以放心地用逻辑运算符表达式来代替条件运算符,否则只能写成 if ... else ...
的写法。
比如:local str = ok and 'yes' or 'no'
,字符串(就算是空串)都是真,所以这样写完全没有问题。