C++/Golang/Rust string 对比

C++ 和 Rust 更倾向于把“拥有一段字符缓冲区”直接建模成一个可以修改的容器;Go 则把 string 建模成“只读字节序列”,把可变缓冲区这个角色明确交给 []byte

Go string / Rust &str:   [ptr][len]
C++ string / Rust String: [ptr][len][capacity]

修改并可能增长一个字符串,需要 capacity 来知道底层缓冲区还有多少空间,是否需要重新分配。Go 的 string 根本没有这个字段,所以设计上就不支持原地修改

语言不可变字符串视图可变、拥有内存的字符串/字节缓冲区
C++std::string_viewstd::string
Rust&strString
Gostring[]byte

Golang string 设置为只读带来的好处:

  • 简化语言模型:Go 明确区分了「只读文本」(string) 和「可变字节缓冲」([]byte)。不可变字符串减少了心智负担和 bug。需要修改时用 []byte
  • 支持安全的共享(零拷贝):因为 string 只读,Go 可以让多个 string 安全地共享同一块底层内存
  • 并发安全:多个 goroutine 之间自由传递 string,无需加锁
  • 可以直接作为 map 的key:不可变才能保证 hash 值稳定

Rust 通过 String(拥有所有权、可变)和 &str(借用、不可变)的区分,以及 mut 关键字,在编译期精确控制可变性和共享——这是所有权系统的一部分。

C++ 的 std::string 就是一个可增长的字符缓冲区(本质是 vector<char>),通过 const 来控制是否可变。

还有一个比较大的区别:Golang 中的 string 被认为是基本数据类型,而其余两者通常认为是复合数据类型

评论