Lua的and与or
很早就知道lua的and与or的巧妙用法:
local str = num==1 and "one" or "not one"
这句话可以简洁的表达如下意思:
local str = ""
if num==1 then
str = "one"
else
str = "not one"
end
类似与c++的:?运算符,一直用着没啥问题,可是前不久遇到了一个很奇怪的bug,查到最后,锁定在这个用法上,举例:
function get_item(config_id, star_lv, server_id)
for _,item in pairs(items) do
if item.config_id==config_id and item.star_lv==star_lv and (server_id and item.server_id==server_id or true) then
return item
end
end
end
我是想:根据config_id, star_lv和server_id来查找物品,其中server_id可以不填(即为nil),若不填,则忽略。
逻辑上是对的,可是运行时候有bug,原因就是:server_id and item.server_id==server_id or true这一句。
原来,lua的and和or返回的值是:使它可以确定其最终值的值
简单测试一下即可看出规律:
print(false and nil) -- false
print(nil and true) -- nil
print(123 and nil) -- nil
print(123 and 456) -- 456
print(false or nil) -- nil
print(nil or 123) -- 123
print(123 or nil) -- 123
print(123 or 456) -- 123
为了验证返回的是值(而不是bool值),我用nil来代替false,用123,456来代替true。
而a = b and c or d这种写法,等同于a = (b and c) or d,也就是根据b and c来决定是否返回d。
结果就很明显了,b and c有2种情况:
- b:true -> c
- b:false -> b
然后再和d做逻辑或运算:x or d,而x or d在:
- x:true -> x
- x:false -> d
分析到这里,可以得出,对于:a = b and c or d来说,若:
- b:true ->
- c:true -> a = c
- c:false -> a = d
- b:false -> a = d
坑已经暴露出来了,a = b and c or d 不等与 C++的a = b ? c : d
只有在c为true的时候,才可以这么用
ps. 只有false和nil才是false,其他都为true