Lua中a.a.a.a赋值后为何a.a等于3而非a?求解答
Lua自引用表赋值问题解析
我按照书中示例做Lua代码实践,代码如下:
a = {} a.a = a a.a.a.a = 3
运行后发现a.a == 3,而非a == 3,想知道原因。
运行环境
- Linux 6.1.0-18-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) x86_64 GNU/Linux
- Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
完整测试代码
a = {} a.a = a print(a.a.a.a) a.a.a.a = 3 print(a) print(a.a) print(a.a.a) print(a.a.a.a)
运行输出
table: 0x562c8c447fc0 table: 0x562c8c447fc0 3 lua5.4: main.lua:37: attempt to index a number value (field 'a') stack traceback: main.lua:37: in main chunk [C]: in ?
问题原因解析
初始时,a = {}创建了一个空表,a.a = a让该表的a字段指向自身,形成循环引用链:a → a.a → a.a.a → ...,所有嵌套的a索引最终都指向同一个表对象。
当执行a.a.a.a = 3时,Lua的赋值逻辑是从左到右依次求值索引,最后给最右侧的字段赋值:
- 先计算
a.a.a:因为a.a等于a,所以a.a.a仍然是a; - 随后给这个结果(即表
a)的a字段赋值为3,这等价于直接执行a.a = 3。
这就打破了原本的循环引用:此时a本身还是最初的表,但a.a已经被修改为数字3,不再指向原表。
输出对应说明
- 第一个
print(a.a.a.a):赋值操作前,所有嵌套的a索引都指向原表,因此输出表的内存地址; print(a):a未被修改,仍然是原表,输出地址;print(a.a):此时a.a已被赋值为3,输出数字3;print(a.a.a):试图对数字3执行索引操作(取3.a),Lua不允许对非表/用户数据类型进行索引,因此抛出错误。
内容的提问来源于stack exchange,提问作者Moncak
相关产品推荐
相关产品推荐

