我有一些正在使用以下语法的Lua代码:
if (foo == nil or foo == '') then
foo = "some default value"
end
if语句的目的是测试foo不是空字符串,也不是nil值。
这段代码能否简化为一个if语句而不是两个?
你可以做的一件简单的事情是将测试代码封装到一个函数中。
local function isempty(s)
return s == nil or s == ''
end
if isempty(foo) then
foo = "default value"
end
string.len
函数。但是,通过执行 s ~= ''
来检查该字符串长度是否大于零也可以起到同样的效果。 - hugomg这段代码能否通过一个if测试来进行简化,而不是两个if测试?
nil
和''
是不同的值。如果您需要测试s
既不是nil
也不是''
,我认为您应该将它们分别比较,因为这样可以使您的意图最清晰。
以下是一些替代方法及其生成的字节码:
if not foo or foo == '' then end
GETGLOBAL 0 -1 ; foo
TEST 0 0 0
JMP 3 ; to 7
GETGLOBAL 0 -1 ; foo
EQ 0 0 -2 ; - ""
JMP 0 ; to 7
if foo == nil or foo == '' then end
GETGLOBAL 0 -1 ; foo
EQ 1 0 -2 ; - nil
JMP 3 ; to 7
GETGLOBAL 0 -1 ; foo
EQ 0 0 -3 ; - ""
JMP 0 ; to 7
if (foo or '') == '' then end
GETGLOBAL 0 -1 ; foo
TEST 0 0 1
JMP 1 ; to 5
LOADK 0 -2 ; ""
EQ 0 0 -2 ; - ""
JMP 0 ; to 7
在Lua 5.1和5.2中,第二个方法是最快的(至少在我的机器上),但是两种方法之间的差异非常小。为了清晰起见,我会选择第一个方法。
foo
为 false
时,第一个和第三个不会像第二个那样执行相同的操作。 - catwell#foo == 0
来检查空字符串,而不是使用foo == ''
- 这样做有可能更快吗? - Nas Banov#foo == 0
比foo ==''
慢一点,在5.1版中稍慢,在5.2和5.3版中要慢得多(通过在我的机器上进行基准测试确定)。 - Mud#{}==0
,#{[2]='foo'}==0
,#{a='b'}==0
。然后,#42
会引发错误;这种行为可能不是期望的...关于速度,#运算符可以被覆盖(在lua 5.2+中)使用一些缓慢的实现,例如:#setmetatable({}, {__len=function()require'socket'.sleep(3)return 7 end})
;最后,您可能会感到惊讶,但默认的#实现对于表格没有保证的顺序(在某些情况下甚至可能是O(n))。 - fcr#str_foo
。 - Nas Banov
'' == true
,nil == false
。 - Kamiccolofoo = (foo or '')=='' and 'default value' or foo
可以翻译为:如果foo为空或未定义,则将其设置为默认值"default value",否则保留原值。 - Egor Skriptunoff