Check if a string isn't nil or empty in Lua
我目前有一些使用以下语法的Lua代码:
1 2 3
| if (foo == nil or foo == '') then
foo ="some default value"
end |
if条件的目标是测试foo既不是空字符串,也不是nil值。
如果测试改为两个,是否可以将这段代码简化为一个?
-
那么,您到底要测试什么foo,bar或foo.bar? 如果您有foo.bar,则可以使用某些功能,例如local function test(foo, bar) { if (foo.bar == nil or foo.bar == ) then foo.bar ="some default value" end end。
-
foo = foo或"某些默认值"
-
假设您不希望foo的foo计数,您可以使用if (not foo) or (foo == ) then ...,否则就那么短。
-
@doog遵守,不会工作。 在Lua中- == true,nil == false。
-
foo = (foo or )== and default value or foo
-
@EgorSkriptunoff是的,..(虽然有点可怕)
-
(对不起,Kamiccolo放了一个无关紧要的.bar,我编辑了问题以删除此假象。以前的版本在所有地方都使用了foo.bar,但我想简化代码示例。)
-
@EgorSkriptunoff它回答了这个问题,但是我敢打赌,OP的意图是为了更简洁一些,即紧凑但可读/表达,而不是相反:)
您可以做的一件简单的事情就是抽象函数内部的测试。
1 2 3 4 5 6 7
| local function isempty(s)
return s == nil or s == ''
end
if isempty(foo) then
foo ="default value"
end |
-
如何计算s的长度是否大于0?例如:foo length是2
-
您可以使用string.len函数。但是要检查它是否大于零,也可以执行s ~= 。
Can this code be simplified in one if test instead two?
nil和''是不同的值。 如果您需要测试s都不是IMO,则应该将两者进行比较,因为这可以使您的意图最清晰。
那和一些替代方案,以及它们生成的字节码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 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时,第一个和第三个不与第二个做相同的事情。
-
如何使用#foo == 0而不是foo == 来检查空字符串-它有更快的机会吗?
-
那不是一个坏主意。 Lua字符串在内部保持其长度,因此您不必计算字符。但是Lua也会实习字符串,因此检查是否相等也不需要查看字符。您只需检查对象是否相同即可。因此,两者都应该很快,但是事实证明,检索字符串长度的代码路径比从VM堆栈中获取两个对象指针进行比较的代码路径稍长,因此#foo == 0比foo == 慢5.1中有一点点,而5.2和5.3中有很多(由我的计算机上的基准测试确定)。
-
@ NasBanov,#运算符还有一些其他问题。还一次为表定义了它,例如#{}==0,#{[2]=foo}==0,#{a=b}==0。然后#42会引发错误;对于速度,关于速度,也可以通过一些缓慢的实现来覆盖#运算符(在lua 5.2+中),例如:#setmetatable({}, {__len=function()requiresocket.sleep(3)return 7 end});最后,您可能会感到惊讶,但是对于表的默认#实现没有保证的顺序(在某些情况下甚至可能是O(n))。
-
@fcr-谢谢您,这是值得深思的-尽管我想当我问我是在暗示知道手头的值是一个字符串时,即#str_foo