問題
最近在寫Lua的時候遇到一個有趣的問題
關於短路求值,我們看一下下面的程式碼
local result = a and b or c;
上面是 Lua 的三元運算,看起來相當合理
如果 a 的判斷是 true 那麼 result 就是 b 不然就是 c
但是在 Lua 中,如果 b 剛好是 nil 或是 false 的話,result 的結果會是 c
這個不是我們要的答案
必須想個辦法解決
為什麼
這個問題的原因是因為 and 和 or 是短路求值
短路求值可以有效的處理下面的程式碼
-- 只有 dog 這個物件存在才會去判斷 dog 是否在睡覺
if dog and dog:isSleep() then
...
...
end
只在有需要的時候才會去執行第二個條件
Lua 做邏輯判斷的時候只有 nil 和 false 是假的,其他都是真的
and 判斷會回傳"假"的那個條件
or 判斷則是回傳"真" 的那個條件
所以
a and b or c
這個判斷下,如果 a 判斷的結果是真,結果應該會是 b or c
可是 b 的內容卻是 nil 或是 false,所以結果就會是 c 了
如果 a 判斷的結果為假,那麼 and 就不會處理
直接進行 or 判斷,這個時候的結果會是 c
也就是說,只要 b 的內容是 nil 或是 false 的話
這個判斷的結果一定會是 c
解決
有很多方式可以避開這個問題
比如改成
local result = not a and c or b;
或是
local result = c;
if a then
result = b;
end
但是這些都是治標不治本(這邊是假設你一定要用三元運算子來處理邏輯)
最好的方式是用 table 將數值包裝起來,等判斷完再取值
-- best solution
local result = (a and {b} or {c})[1];
搞定!
回家收工!
參考
短路求值
Lua邏輯判斷