【问题标题】:Operator # nil values at end of array运算符 # nil 值在数组末尾
【发布时间】:2014-11-12 05:36:15
【问题描述】:

我用:

b.x = {}
a = Obj()
a:AddParams("a", "b", "c")

...
...

function Obj:AddParams(a, b, c, d, e)
  table.insert(b.x, {["one"] = a, ["two"] = b, ["three"] = c, ["four"] = d, ["five"] = e})
end

然后我打印 #b.x 并打印 1。它不应该打印 2,因为 # 运算符计算 nil 值并且我只在 a:AddParams 上给出前 3 个参数,而后两个为 nil?非常感谢

【问题讨论】:

  • 发布您的确切代码和结果。

标签: arrays lua


【解决方案1】:

它不应该打印 2,因为 # 运算符计数 nil 值

不,恰恰相反!

首先,将nil 添加到表的整个概念是无效的。您可以在表中存储任何内容除了 nil。这样做会删除该键(索引)中已经存在的值,但不会在其中插入 nil。这就像数学上的空集∅,用于将空性表示为一个实体,但不是有形的价值/对象。访问表中不存在的任何索引会给你nil,你不必插入一个就可以看到它们在那里;任何不存在的键都有值nil,表示该值不存在。

> a = { }
> print(a[1])
nil
> a = { "abc" }
> print(a[1])
abc
> a[1] = nil   -- this is just erasing 'abc' from the table; not add/insert nil
> print(a[1])
> nil

因此它们从不构成表格的大小。

长度运算符返回序列中元素的计数 n;序列是一个具有值的表(当然是非零 - 这是隐含的,因为如上所述,人们永远不能插入零)由从 1 开始扩展到某个正整数 n 的连续整数索引。如果它们不是连续的(被孔破坏),则不应使用运算符#Lua manual 明确指出,仅当表是序列时才定义使用 #。但是请注意,非整数键与表的序列性质无关。

【讨论】:

  • 您的解释是正确的,但有点误导。序列必须以键 1 开头。包含序列的表可以具有带有非正整数键的附加值,即不限于“数组”。
  • 你是对的;做了一个彻底的改造来彻底解释这个概念。
【解决方案2】:

现在您已经阐明了您的代码在做什么:

b.x 实际上是一个元素表,其中单个元素是另一个表,因为您的代码如何调用table.insert

b.x = {

  [1] = {                          <======= this single element in the top-level
    ["one"] = "a",                          b.x table is what the # operator counts
    ["two"] = "b",                          when you apply it as #b.x
    ["three"] = "c"
  }

}

因此,无论您将什么传递给函数,调用 #b.x 将始终返回 1,因为您始终将该 table 作为单个元素添加到您初始化 @987654328 的原始空表中@成为。

但是请注意,即使您没有创建此嵌套表,从# 返回的值仍然不是您所期望的。 # 运算符确实 not 计数 nil 值。 # 运算符计算的是 从 1 开始的表的连续数字索引的长度(和 is not defined for tables with non-sequential numerical indices)。因此,

  • #{ [1]="a", [2]="a" } 评估为 2
  • #{ [1]="a", [3]="a" } 没有在 Lua 标准中定义,因为索引不连续
  • #{ [1]="a", ["two"]="b" } 计算结果为 1(因为 "two" 不是数字,而是字符串)。

上一个答案...

不确定你从哪里得到 1:

> a = {}
> a[1] = "a"
> a[2] = "b"
> a[3] = "c"
> a[4] = nil
> a[5] = nil
> print(#a)
3

(请注意,将 nil 分配为表末尾的值没有任何作用 - 省略 a[4]a[5] 行会得到相同的结果。)

你是否真的跳过了a[2]?这将导致 #a 为 1,因为它只计算从索引 1 开始的连续项目。

【讨论】:

  • 您是否在任何地方使用... 语法?查看您的问题的小型独立复制品会很有用。
  • 将我的问题编辑为确切的问题:)
  • "one"1 对于 Lua 表索引来说是非常不同的东西。
  • Nit: 是的,#{[1]='a', [3]='a'} 的计算结果为1 and not 3,但推理存在缺陷。假设我们有这个{[1]='a', [2]='b', [3]='c', [5]='e'},虽然# 会给出3(根据你的推理),但这是不正确的。 Lua manual specifically calls out # 运算符仅用于序列;因此,在非序列上使用它是不确定的,尽管它有时看起来是正确的。
  • What the # operator counts is the number of continuous counting number indices starting at 1 in the table. 这并不完全正确。它返回一些索引i,其中t[i] ~= nilt[i+1] == nil,如果t[1] == nil,则可能为0。这意味着它可能在有孔的数组中计算nils,也可能不计算。
【解决方案3】:

您正在构建一个表并将其插入到具有键 1 的空表中。如果要插入多个元素,则必须为每个元素调用 insert。

而且,您正在构建的表具有字符串键,它们根本不会影响 #。

我建议您使用带有调试器的 IDE。请参阅 [lua] 标签 wiki。

【讨论】:

    猜你喜欢
    • 2013-11-02
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多