为何Zig标准库中极少使用指针作为函数参数?
首先得纠正一个误解:不是所有传值都会带来明显的性能开销,很多时候传值反而比传const指针更高效,这也是Zig这么做的核心原因之一,具体可以从这几个角度看:
小类型拷贝的成本可以忽略,甚至比指针更优
对于像u32、f64这种大小不超过机器字的类型,直接传值就是一个寄存器操作,比传指针再解引用(要走内存访问)快得多。就算是稍微大一点的类型,比如Zig里的Slice(本质是包含指针和长度的胖结构体),传值也就是拷贝两个机器字,和传单个指针的成本差不多,但不用额外处理指针的解引用逻辑。避免别名问题,让编译器更易优化
如果你传的是const指针,编译器必须考虑这个指针指向的内存会不会被其他地方的代码修改(哪怕是const,也可能存在别名),这会限制编译器的优化空间。而传值的话,函数拿到的是独立的副本,编译器可以放心地做各种优化,比如把值存在寄存器里,不用频繁回写内存。值语义更符合Zig的设计哲学
Zig推崇值语义优先,这样的代码更直观、更不容易出错。传值的话,你不用去纠结指针的生命周期、有没有空指针风险,函数的行为完全由输入的值决定,逻辑更清晰。比如你传一个struct进去,直接用就行,不用写.*或者->来解引用,代码可读性更高。并非完全不用const指针,而是场景特定
当你处理的是超大类型(比如几百字节以上的结构体),或者需要共享内存(比如跨线程访问)的时候,Zig标准库也会用const指针。但这种场景在日常代码里占比不高,所以你会看到大部分情况都是传值。
总结一下:这不是单纯的惯用写法,而是Zig结合自身类型系统、性能优化和设计哲学做出的合理选择,大部分场景下传值比const指针更高效、更安全、更易维护。
内容的提问来源于stack exchange,提问作者kupper

