You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Zig中使用ArrayList时,变量赋值为何会改变函数行为?

为何Zig中ArrayList赋值给局部变量后操作异常?

问题出在Zig的类型语义上:ArrayList(T)是值类型,不是引用类型。当你把self.stacks.items[source - 1]赋值给局部变量source_list时,你做的是完整的结构体拷贝,而非创建指向原ArrayList的引用。

错误代码的问题分析

看你最初的实现:

fn moveCrates(self: *BunchOfStacks, amount: usize, source: usize, dest: usize) !void {
    var source_list: ArrayList(u8) = self.stacks.items[source - 1];
    const source_height = source_list.items.len;
    const crate_slice = source_list.items[(source_height - amount)..];
    try self.stacks.items[dest - 1].appendSlice(crate_slice);
    source_list.shrinkRetainingCapacity(source_height - amount);
}
  • source_list是原ArrayList的副本:它拷贝了原ArrayList的allocator、items切片和capacity字段。
  • 你调用source_list.shrinkRetainingCapacity(...)时,只会修改这个栈上副本的items切片长度,完全不会影响self.stacks里的原ArrayList。
  • 虽然crate_slice指向的是原底层数组的内存(因为切片是指针+长度),但原栈的长度没有被正确缩短,后续循环调用时,原栈的状态始终是错误的,看起来就像source_list始终指向同一个ArrayList。

正确代码的逻辑

第二段代码直接操作self.stacks.items[source - 1]:

fn moveCrates(self: *BunchOfStacks, amount: usize, source: usize, dest: usize) !void {
    const source_height = self.stacks.items[source - 1].items.len;
    const crate_slice = self.stacks.items[source - 1].items[(source_height - amount)..];
    try self.stacks.items[dest - 1].appendSlice(crate_slice);
    self.stacks.items[source - 1].shrinkRetainingCapacity(source_height - amount);
}

所有操作都直接作用于self.stacks中的原ArrayList实例,修改的是它的实际状态,因此行为符合预期。

优化写法(兼顾简洁与正确性)

如果想用局部变量简化代码,应该使用指针指向原ArrayList,而不是赋值拷贝:

fn moveCrates(self: *BunchOfStacks, amount: usize, source: usize, dest: usize) !void {
    var source_list = &self.stacks.items[source - 1];
    const source_height = source_list.items.len;
    const crate_slice = source_list.items[(source_height - amount)..];
    try self.stacks.items[dest - 1].appendSlice(crate_slice);
    source_list.shrinkRetainingCapacity(source_height - amount);
}

这里source_list是指向原ArrayList的指针,所有对它的操作都会直接修改self.stacks中的实例,既避免了重复写长表达式,又保证了逻辑正确。

内容的提问来源于stack exchange,提问作者Drum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 03:10:14