布林值類型提案

lua-users home
wiki

VersionNotice:此頁面適用於 Lua 4 和沒有內建布林值類型的舊版 Lua。自 Lua 5.0 起提供內建的布林值類型。

以下是解決 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 的實作

我建立了一個 Lua 4.0 的修補程式來實作布林值類型。它的行為並不完全如上所述——andor 兩個運算子不同。在 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 假設除了 nilfalse 之外,一切都為 true。有 3 個新的 API 函數:lua_pushfalse、lua_isfalse 和 lua_istrue(非 nil 也非 false)。新的標籤命名為 LUA_TFALSE,類型字串為「false」。

一些警告

啊,而且修補程式在此:Files:wiki_insecure/users/froese/bool-patch-1

-- EdgarToernig?

太棒了!關於此小修訂程式的一點小抱怨...在新增定義 (LUA_REFFALSELUA_TFALSE) 時,沒有理由變更現有的定義。對新 opcode 亦同。這樣可以減少與其他修訂程式的衝突。--JohnBelmonte

或許可以新增設定為 1 的全域性 true 來達到此目的。


最近的變更 · 喜好設定
編輯 · 紀錄
上次編輯於 2013 年 7 月 14 日下午 8:23 GMT (diff)