Lua中使用函数修改链表失效问题咨询
Lua链表函数修改失效的原因与解决方法
这问题我太熟了!核心原因就是Lua的参数传递是值传递,你在add_node函数里操作的root只是外部变量的一个副本,根本没改动到原来的链表头。
咱们拆解来看两种场景的差异:
- 当你直接执行
root={nxt=root, val=1}时,你是直接修改了当前作用域下的root变量,让它指向新创建的节点,新节点的nxt又关联原来的root,链表结构完全正确,所以遍历能拿到两个值。 - 但用
add_node(root)调用函数时,函数里的root参数是外部root的一份拷贝。你在函数内做root={nxt=root, val=1},只是修改了这个局部的root副本,外部的root变量完全没变化,还是指向最初的那个节点,所以遍历只能打印第一个节点。
那怎么解决这个问题?给你两个常用方案:
让函数返回新的链表头
把add_node改成返回新节点的形式,调用时手动更新外部的链表头:function add_node(root) return {nxt=root, val=1} end -- 调用时更新外部root root = add_node(root)这样外部的
root就会被替换成新的节点,链表结构自然正确。用表包装链表头(模拟引用传递)
把链表头放在一个表容器里,因为Lua的表是引用类型,传递的是引用的副本,修改表内的元素会同步影响外部的表:-- 用表包装初始节点 local root_wrap = {node = {val=0, nxt=nil}} function add_node(wrap) -- 修改容器内的节点,外部会同步感知 wrap.node = {nxt=wrap.node, val=1} end add_node(root_wrap) -- 遍历时以root_wrap.node作为链表头
简单总结:Lua里没有真正的引用传递,函数参数传的都是值的副本——如果是基本类型(数字、字符串、nil),修改副本不影响原变量;如果是表,只有修改表的内容才会影响原表,直接给参数赋值新表的话,还是只改了副本。你之前的add_node就是直接给参数赋值新表,所以才没生效。
内容的提问来源于stack exchange,提问作者Colin
相关产品推荐
相关产品推荐

