【问题标题】:LUA: #table key reference suddenly alters table entriesLUA:#table 键引用突然改变表条目
【发布时间】:2021-07-01 13:45:58
【问题描述】:
--tables for the 1st example
local table1EX1={1,2,3}
local table2EX1={4,5}
local temp={}

-- 1st example:
temp=table1EX1
for i=1,2 do
  temp[3+i]=table2EX1[i]
  print("#temp = "..#temp)
end

-- output from the print command:
-- #temp = 4
-- #temp = 5
-- this is what I intended to do but I need it to adapt to a changing table size

--tables for the 2nd example
local table1EX2={1,2,3}
local table2EX2={4,5}
local temp={}

-- 2nd example:
temp=table1EX2
for i=1,#table2EX2 do
  temp[#table1EX2+i]=table2EX2[i]
  print("#temp = "..#temp)
end

-- output from the print command:
-- #temp = 4
-- #temp = 6
-- this is what I tried and where I noticed something is wrong

#table_name 只返回一个值,即命名表中从第一个条目到最后一个条目的数值范围。

确认这一点的测试: #1:

local tab={-1,0,_,nil,"a",nil,"x",_,3}
print(#tab) -- returns 9

#2:

local tab={1,2,3}
print(#tab) -- returns 3
tab[2]=nil
print(#tab) -- returns 3

#3:

local tab={1,2,3}
print(#tab) -- returns 3
tab[3]=nil
print(#tab) -- returns 2

我不明白在 example#1 和 example#2 之间出了什么问题以及为什么:代码应该工作相同:table1EX1 和 table1EX2 永远不会收到对其内容或大小的任何更改,因为 temp 变量用于存储两种情况下的值。然而在 example#2 中,代码突然导致 table1 的内容发生变化,从 print 命令输出可以看出。

虽然可以通过分配变量来避免整个问题,例如...

--tables for the 2nd example
local table1EX2={1,2,3}
local table2EX2={4,5}
local temp={}

-- 2nd example:
temp=table1EX2
local x,y=#table2EX2,#table1EX2
for i=1,x do
  temp[y+i]=table2EX2[i]
  print("#temp = "..#temp)
end

...我想了解问题所在以及原因。 在这种情况下,英文中正确调用的“#”是什么?夏普,就像在 C# 中一样?菱形,就像字典上显示的那样?

【问题讨论】:

  • # 长度操作符没有为非序列表定义,它应该只在你知道你的表是一个序列时使用,否则结果将是不可预测的。至于我们所说的英文#,它有很多名字number signpoundhashtag。我倾向于支持数字符号,或者如果特别是 lua,我会称之为长度运算符。
  • Lua 中# 操作符的规则很简单,据我所知:它告诉 如果 是一个序列 的表的长度是一个序列没有任何零值。强烈建议不要在任何其他情况下使用。
  • (它也明确指出,如果序列中有一个 nil,那么它可以返回任何数字,使得下一个为 nil。请不要在序列中包含 nil!)跨度>

标签: lua


【解决方案1】:

让我们看看你在这里做什么。见 cmets

示例 1

local table1EX1={1,2,3} -- create a table with 3 elements
local table2EX1={4,5} -- create another table with 3 elements
local temp={} -- create an empty table

temp=table1EX1 -- temp now refers to table1EX1
-- in a loop append the 2 elements of table2EX1 to table2EX1 (or temp, same table)
for i=1,2 do
  temp[3+i]=table2EX1[i] -- first run temp[3+1], second temp[3+2]
  print("#temp = "..#temp)
end

代替

local temp = {}
temp = table1EX1

简单写

local temp = table1EX1

示例 2

local table1EX2={1,2,3} -- create a table with 3 elements
local table2EX2={4,5}  -- create a table with 2 elements
local temp={}  -- create an empty table

temp=table1EX2  -- temp now refers to table1EX2
-- in a loop from 1 to #table2EX2 (2)
for i=1,#table2EX2 do
  temp[#table1EX2+i]=table2EX2[i] -- first run temp[3+1], second temp[4+2]
  print("#temp = "..#temp)
end

您向 temp 添加了 1 个元素,因此您向 table1EX2 添加了 1 个元素,因为两者都引用同一个表。因此在第二个循环中#table1EX24。这就是示例 1 的不同之处。

通过引用复制表值! local temp = table1EX1 不会将任何值从 table1EX1 复制到 temptemp 只是对table1EX1 所指表的另一个引用。

local tab={-1,0,_,nil,"a",nil,"x",_,3}
print(#tab) -- returns 9

这很危险。请参考Lua手册:https://www.lua.org/manual/5.4/manual.html#3.4.7

当t是一个序列时,#t返回它唯一的边框,对应于 序列长度的直观概念。当 t 不是 序列,#t 可以返回它的任何边界。 (具体取决于 表的内部表示的详细信息,这反过来又可以 取决于表的填充方式及其内存地址 非数字键。)

只有知道 t 是一个序列时才使用长度运算符。这是一个整数索引 1,..n 没有任何间隙的 Lua 表。

在这种情况下,英文中正确调用的“#”又是什么?锋利的, 就像在 C# 中一样

它是数字符号或哈希。在 Lua 的情况下,它被称为 length 运算符

阅读此https://en.wikipedia.org/wiki/Number_sign

【讨论】:

    猜你喜欢
    • 2020-12-27
    • 2021-12-11
    • 2010-12-18
    • 1970-01-01
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多