如何在Lua中检查一个值是否为空?

21

在Lua中,检查某个变量是否为空的正确方式是什么?if x == ""f x ~= "" 似乎都不起作用。


空的意思是指里面没有输入任何内容。 - Village
2
你不能“键入”值到变量中。你能给出更精确的定义吗?因为一个包含 "" 字符串的变量并不是“空”的。它有一个字符串,即 ""。这是一个有效的字符串,因此不是“无”。 - Nicol Bolas
好的,那么我的“空”是指 "" - Village
那么你的代码在哪个方面出了问题?x = ""; if x == "" then print("empty"); else print("not empty"); end 是有效的 Lua 代码。它将始终打印“empty”。你的问题是当你没有 x = "" 部分时它就无法工作吗?或者换句话说,仅仅因为 认为 "" 表示空并不意味着 Lua 也这样认为。 - Nicol Bolas
请提供一些上下文信息:您是否在任何时候将值设置为 ""?您是否从输入中读取该值?这是库返回的值吗?这将澄清您所说的“空”(一个非常主观的术语),从而使我们能够更有效地帮助您。 - Deco
我正在使用Lua在ConTeXt中。值为空,例如,\macro{} - Village
4个回答

17

Lua是一种动态类型的语言。

任何变量都可以持有以下类型之一:nilbooleannumberstringtablefunctionthreaduserdata

对于一个没有值的表中的任何变量(包括全局变量所在的_G表),在索引时都返回nil。当你将一个表变量设置为nil时,它实际上是“未声明”(完全从内存中删除该条目)。

当一个local变量被声明时,如果不立即赋值,它将被赋予一个值nil。与表变量不同的是,当你将一个local变量设置为nil时,它并不会“未声明”(它只是拥有了一个nil值)。

在Lua中,空字符串("")仍然是一个“值”,只是它是一个字符长度为零的字符串。


我认为说“当你将一个变量设置为nil时,它实际上是'未声明'的”有点不准确——nil除了在表内部以外都是一个真值,所以例如,一个具有值nil的局部变量仍然会遮蔽周围作用域中的变量... - snogglethorpe
1
你说得完全正确;那个语句是针对表格对而非所有变量的。答案已经修改以反映这一点。 - Deco
如果是 nil 的话 print("nil 是真的") 否则 print("nil 不是真的!") end --> nil 不是真的! - handle
@handle 嘿...抱歉,我的“真实值”指的是“实际值”,即我在俚语上使用“true”,而不是Lua的意思... ^^; - snogglethorpe
非常抱歉,虽然这是一个非常老的答案 - 我来到这里是因为它是重复的根源。阅读答案并不能回答我的问题。也许答案在技术上被隐藏在其中 - 对于我这样的非程序员来说,它谈论了原因和限制,并避免了有用的答案。在关闭之前,重复的某个人很快就在那里发布了它。只是想在这里点赞。 - Shegit Brahm
这个回答没有回答问题。 - undefined

5

我最近也遇到了这个问题。如果数据库值是“空白”(不是null),LuaSQL会返回空字符串。虽然方法有些hacky,但以下是我的解决方案:

if (string.len(x) >= 1) then
    ...
end

4
我假设OP的意思是“如何判断一个变量是否未被赋值”。

例如:

local x

变量x是“空”的,它被初始化为“nil”。(不是文本“nil”,而是一个枚举值,表示变量未分配。在Lua中,它被定义为nil,在其他一些语言中,它被定义为NULL。)
现在给x赋值。 例如:
x=""

现在x不是nil了。 另一个例子:

x=0

x不是nil。

尝试运行此代码,它应该让您清楚地了解情况。

local x
if x==nil then print("x is nil") end

x=0
if x==nil then print( "This line won't be written") end

x=""
if x==nil then print( "and this line won't be written") end

第一个if语句将会被判定为真,因此打印语句将会被调用。第二个和第三个if语句都是假的,因此打印语句不会被执行。

总之,使用“==nil”来检查变量是否为空(更准确地说是“nil”)。


1

你的字符串可能包含空格、换行符或其他不可见字符。所以你认为它是“空的”,但实际上并不是。这通常发生在你从用户那里获取输入时,必须键入“回车”才能完成——“回车”最终会出现在字符串中。

你需要的是一个函数,告诉你字符串是否“空白”——即为空,或者是一系列空格/制表符/换行符。以下是一种方法:

function isBlank(x)
  return not not tostring(x):find("^%s*$")
end

使用方法:

if isBlank(x) then
  -- ...
end

2
这相当低效;not not string.find(x,"^%s*$") - daurnimator
好的,你的版本肯定是正确的(一旦你包括省略的tostring调用)。我不确定它是否显著更快。你为什么这样认为? - kikito
1
不是不是?我是不是漏掉了什么,还是这只是个打字错误。去掉"不是不是"后,它仍然能正常工作,而且更容易阅读。 - Leif Högberg
2
“not not”是Lua中常用的习语,意思是“转换为布尔值”。我并不经常使用它,但由于OP似乎是Lua新手,我想他会更容易理解一个返回truefalse的函数。此外,string.find返回多个值,这可能会在你刚学习该语言时产生一些副作用和意外情况。而“not not”则可以解决所有这些问题。 - kikito
本地变量xd赋值为空格字符串" "。 函数名为isBlank,意味着对于xd,它应该返回true。 对于一个空字符串,not tostring(x):find("^%s*$")将返回false。 这就是为什么有两个not。这就是回答者所指的, 因为find默认返回不同的值。 - DreTaX
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接