布林值類型提案 |
|
以下是解決 Lua 將 nil 用於 false(本網站尚未說明任何地方)的問題的計畫。仍需要更多的工作。
新增一種含有單一值 false
的「false」類型。(這類似於「nil」類型有一個單一值 nil
,並遵循 Scheme。)範例
print(type(false)) --> "false"
關係運算子傳回 false 表示為 false,傳回非 false
/nil
的值表示為 true。範例
5 > 6 --> false 5 ~= false --> "true" nil == false --> false
邏輯運算子將非 false
/nil
的值視為 true。如果邏輯運算子的結果是 nil
(因為與 nil 連接/分離),它會轉換為 false
。換句話說,關係運算子和邏輯運算子的結果永遠不會是 nil
。範例
nil and 5 --> false nil or 5 --> 5 5 and false --> false 5 or false --> 5 not 5 --> false
壞消息...以下是會中斷的範例。不過,看起來好像都不是理智的程式設計模式。
if (a>b) == nil then ... end -- testing boolean expression against nil var3 = var1 or var2 -- expecting possible nil var3 var3 = var1 and var2 -- "
好消息...此變更允許程式區分從布林值表達式指定變數和不存在的變數。例如
-- try one of these --IsOk = nil --IsOk = SomePredicateFunction() --IsOk = "I don't know" -- new style test for non-existance if IsOk == nil then ... end -- new style test for existance if IsOk ~= nil then ... end -- new style test for true/false (assuming value is not nil) -- also: old style test for existance (assuming value is not false, -- which holds for legacy code) if IsOk then ... end
我建立了一個 Lua 4.0 的修補程式來實作布林值類型。它的行為並不完全如上所述——and
和 or
兩個運算子不同。在 Lua 中,它們不是嚴謹的布林值運算子;它們可能產生非布林值結果,並且如果運算式的結果是由第一個運算元得知,它們不會評估第二個運算元。因此,我這樣定義它們
and(a,b): if a==nil or a==false then return a else return b end or(a,b): if a~=nil and a~=false then return a else return b end
其中 b 僅在需要時評估。使用這個定義,經常搭配這些運算子使用的 Lua 架構會比以前一樣的行為。亦即,你上面提供的範例(var3 = var1 and/or var2
)可能會在 var3 中產生 nil。
其他所有內容都如上所述:所有比較運算子和 not
運算子都傳回 false(現在為保留的關鍵字)或數字 1 表示為 true。條件式陳述(if/while/repeat)和 not
假設除了 nil
和 false
之外,一切都為 true。有 3 個新的 API 函數:lua_pushfalse、lua_isfalse 和 lua_istrue(非 nil 也非 false)。新的標籤命名為 LUA_TFALSE,類型字串為「false」。
一些警告
if x==nil
」不再與「if not x
」相同,而「if x~=nil
」不再與「if x
」相同。最好檢查你的程式...啊,而且修補程式在此:Files:wiki_insecure/users/froese/bool-patch-1
-- EdgarToernig?
太棒了!關於此小修訂程式的一點小抱怨...在新增定義 (LUA_REFFALSE
、LUA_TFALSE
) 時,沒有理由變更現有的定義。對新 opcode 亦同。這樣可以減少與其他修訂程式的衝突。--JohnBelmonte
或許可以新增設定為 1 的全域性 true
來達到此目的。