布尔类型提案 |
|
以下是一个关于修复 Lua 中使用 nil 表示 false 的问题的方案(此问题尚未在本网站上解释,请参考 lua-l)。该方案仍需进一步完善。
添加一个新的类型 "false",它只有一个值 false
。(这类似于类型 "nil" 只有一个值 nil
,并遵循 Scheme 的规范。)示例
print(type(false)) --> "false"
关系运算符对于 false 返回 false
,对于 true 返回除 false
/nil
之外的值。示例
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
)可能会将 nil 赋给 var3。
其他所有内容都与上面描述的一致:所有比较运算符和 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
" 相同。最好检查一下您的程序...
啊,补丁在这里:文件:wiki_insecure/users/froese/bool-patch-1
-- EdgarToernig?
太好了!关于补丁的一个小抱怨... 在添加新的定义(LUA_REFFALSE
,LUA_TFALSE
)时,没有理由更改现有的定义。同样适用于新的操作码。这减少了与其他补丁的冲突。--JohnBelmonte
也许应该通过添加一个设置为 1 的全局 true
来完善它。