检查 Lua 中的字符串是不是为 nil 或为空

Posted

技术标签:

【中文标题】检查 Lua 中的字符串是不是为 nil 或为空【英文标题】:Check if a string isn't nil or empty in Lua检查 Lua 中的字符串是否为 nil 或为空 【发布时间】:2013-11-08 23:43:24 【问题描述】:

我目前有一些使用以下语法的 Lua 代码:

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 的 'false' 计数,您可以使用 if (not foo) or (foo == '') then ...,否则它会尽可能短。 @doog 坚持,不会工作。在 Lua 中 - '' == true, nil == false. foo = (foo or '')=='' and 'default value' or foo 【参考方案1】:

您可以做的一件简单的事情是在函数中抽象测试。

local function isempty(s)
  return s == nil or s == ''
end

if isempty(foo) then
  foo = "default value"
end

【讨论】:

如果 s 的长度大于 0,你如何计算?例如:foo 长度为 2 你可以使用string.len函数。但是要检查它是否大于零,s ~= '' 也可以。 thnx... 虽然问题是关于检查它是否 not 为空:p【参考方案2】:

如果测试不是两个,这个代码可以简化为一个吗?

nil'' 是不同的值。如果您需要测试 s 两者都不是,IMO 您应该与两者进行比较,因为它使您的意图最清楚。

这和一些替代方案,以及它们生成的字节码:

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 中是最快的(无论如何在我的机器上),但差别很小。为了清楚起见,我会选择第一个。

【讨论】:

foofalse 时,第一个和第三个不做与第二个相同的事情。 使用#foo == 0 代替foo == '' 来检查空字符串怎么样?它有可能更快吗? 这不是一个坏主意。 Lua 字符串在内部保持其长度,因此您不必计算字符数。但是 Lua 也实习字符串,所以检查相等性也不需要查看字符;您只需检查对象是否相同。所以两个 应该 都很快,但结果是检索字符串长度的代码路径略长于从 VM 堆栈中获取两个对象指针以比较它们的代码路径,所以#foo == 0在 5.1 中比 foo == '' 慢一点,在 5.2 和 5.3 中慢很多(由我机器上的基准测试确定)。 @NasBanov,# 运算符还有一些其他问题。这一次也是为表定义的,例如#==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

以上是关于检查 Lua 中的字符串是不是为 nil 或为空的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 中检查 NSArray 是不是为空或为空?

spark中的isNullOrEmpty函数检查数据框中的列是不是为空或空字符串

如何检查Lua中的值是不是为空?

Lua:明确检查nil后字符串为nil

Rails 4:收到以下错误:表单中的第一个参数不能包含nil或为空

如何检查数据读取器是不是为空或为空