为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 在修改/写入时复制字符串吗?

Golang 在修改/写入时复制字符串吗?

Go
呼如林 2023-07-10 17:23:07
鉴于下面的示例,幕后实际发生了什么?package mainimport "fmt"func main() {  s := "Hello"  t := s // t shares the same data as s  s += "World" // a new string is created  t += "There" // a new string is created.  fmt.Printf("%s %s\n", s, t)}输出:HelloWorld HelloThere问题是golang什么时候会判断需要创建新的副本呢?
查看完整描述

2 回答

?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

在 Go 中,字符串值是read-only字节切片,您无法更改其元素(不可变)。由于它是一个切片,因此意味着它有一个已定义容量的支持(底层)数组。话虽这么说,我们可以说字符串是一个指向只读后备数组的数据结构。

字符串针对高可重用性进行了优化,因此是只读的。每当您修改字符串时,都会在后台创建一个新字符串(字节切片),这使得操作成本较高。一项建议是将字符串转换为实际的字节切片[]byte(string)并使用字节,或者当程序需要执行大量字符串操作时使用strings.Builder 。

s := "Hello" // backing array for "hello" created; `s` points to the backing array

t := s // `t` a new string structure and points to the same backing array as `s`, 

s += "World" // new backing array created for "HelloWorld"; `s` points to the new backing array

t += "There" // `t` was still pointing to "Hello" and with this operation, a new backing array is created for "HelloThere" and `t` points to it


查看完整回答
反对 回复 2023-07-10
?
喵喵时光机

TA贡献1846条经验 获得超7个赞

经过评论部分对此进行了大量辩论/讨论后,这是我的结论。

Golang 没有写时复制。

这里的+=是显式创建一个新字符串,相当于s = s + "World"创建一个新字符串并将其分配回s

如果你尝试编写以下代码,由于 Golang 字符串的不可变性,将会导致编译错误

t[0] = 'A' // cannot assign to t[0]

因此,Golang 中的所有内容都是显式的,Golang 没有隐式执行任何操作。这就是 Golang 中不存在写时复制的原因。

注意:COW 和不变性并不相互排斥。


查看完整回答
反对 回复 2023-07-10
  • 2 回答
  • 0 关注
  • 112 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信