在Lua中如何管理表?[外部行为示例]

在Lua中如何管理表?[外部行为示例],lua,reference,insert,lua-table,Lua,Reference,Insert,Lua Table,我试图理解一个Lua函数来解析XML格式的字符串,我发现在处理表时出现了一个意外的行为。我将问题总结如下: local stack = {} local top = {} table.insert(stack, top) table.insert(top,{1,2,3}) top={'x','y','z'} print(stack[1][1][1],stack[1][1][2],stack[1][1][3]) print(top[1],top[2],top[3]) >> 1

我试图理解一个Lua函数来解析XML格式的字符串,我发现在处理表时出现了一个意外的行为。我将问题总结如下:

local stack = {}
local top = {}
table.insert(stack, top)

table.insert(top,{1,2,3})

top={'x','y','z'}

print(stack[1][1][1],stack[1][1][2],stack[1][1][3])
print(top[1],top[2],top[3])

>> 1 2 3
>> x y z

我不明白为什么这两个输出不一样。如果通过引用将top插入到堆栈中,如果我没有用
top={'x','y','z'}
覆盖top,第一个输出将是有意义的。当我直接输入top的值时,stack为什么不受影响


看起来好像
top={'x','y','z'}
top创建了另一类实例,这样就保留了堆栈所指向的值。是这样吗?当您想详细了解Lua文档时,Lua文档是稀缺的,而我还没有找到任何关于这方面的信息。在我看来,如果没有明确规定,这是一种危险的行为

问候

\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu


我犯了一个错误:
table.insert(top,{1,2,3})
top={'x','y','z'}
不同,它与
top[1]={'x','y','z'}
相同

因此,重新表述原始问题,我们有代码:

local stack = {}
local top = {}
table.insert(stack, top)

table.insert(top,{1,2,3})

top[1]={4,5,6} -- it does change stack

top = {'x'}

print(stack[1][1][1],stack[1][1][2],stack[1][1][3])
print(top[1][1],top[1][2],top[1][3])

>>   4      5     6
>>  nil    nil   nil
现在,我看到第二个输出非常正常,但我仍然怀疑预测第一个输出

如果我替换
top={'x'}
for
top[1]='x'

>> nil nil nil
>> nil nil nil
我已经读了这一部分,但我仍然不完全知道出了什么问题。 如果我犯了一个愚蠢的错误,很抱歉,但我看不出来。

Lua对值而不是变量进行操作

试着替换

top={'x','y','z'}


表是Lua中的值。每个表都是一个独立且不同的值。变量不是值的名称;它们只不过是能装一段时间的盒子

多个变量可以引用同一个表。因此,在执行
top={}
之后,变量
top
具有对表的引用。通过执行
table.insert(stack,top)
,现在
top
stack[1]
都引用了同一个表

如果执行
top={'x'}
,则更改
top
中存储的表。你在那个盒子里放了一个新东西。但是
stack[1]
仍然引用设置到其中的表

这与这样做没有什么不同:

var1 = 5;
var2 = var1;
var1 = 10;
var2
仍然是5;它没有变成10
var2
var1
没有连接。它只取
var1
当时的值

让你感到困惑的是表格本身和它的内容之间的差异

top
包含对表的引用
top[1]
表示获取由
top
引用的表的第一个元素。如果您为
top[1]
分配了某些内容,则您没有修改变量;您正在修改该变量引用的表的内容

top[1]={4,5,6}
修改当前由
top
引用的表中存储的内容。此时,该表也被
stack[1]
引用。因此,您可以通过
top
stack
访问该表


一旦您通过执行
top={'x'}
更改了表
top
引用的内容,这就不再正确了<代码>顶部现在引用另一个表。但是它用来引用的表仍然可以通过
stack

top={'x','y','z'}
为top创建另一种类型的实例,这样就可以保留stack指向的值。是这样吗对这就是正在发生的事情。为了更容易理解,请注意您的表没有名称。只有变量可以。因此,
top
在RHS中表示“在程序当前行执行时变量“top”指向的值”,谢谢您的评论。我已经编辑了这个问题。我仍然想知道,为什么在这种情况下,top会表现得像它一样。当你意识到自己的错误时,请不要改变你问题的主题。你的问题已经回答了——就这样吧。就新问题问一个新问题。这个问题到处都是,我在处理你需要的东西时遇到了麻烦。我的错误并没有解释我的问题,它只是解释了为什么两个输出不一样。主题是一样的,这就是为什么我没有问一个新问题。我只是简单地重新表述了这个问题,给出了一个更具体的例子,说明我要求解释的行为。你的问题是为什么输出不一样。回答了。谢谢,这让我意识到我在想那个表时犯了一个错误。insert(top,{1,2,3})与top={'x','y','z}是一样的。我编辑了这个问题,因为我仍然不知道发生了什么。好的,我想我终于明白了。这有点像我建议创建一个新的top“实例”。更准确地说,一个新表与变量top相关联。这就是我所怀疑的,但让我困惑的是,我知道什么时候修改了值,或者变量什么时候被分配到一个新表。因此,在我问题的最后,当我建议写
top[1]='x'
时,我认为它会使top[1]指向一个新的值,但实际上它是变化的。棘手的事情是确定何时修改值或引用新表。赋值总是会改变变量/索引所包含的内容,并且永远不会修改它之前的值。
var1 = 5;
var2 = var1;
var1 = 10;