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

鉴于下面的示例,幕后实际发生了什么?


package main


import "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什么时候会判断需要创建新的副本呢?


呼如林
浏览 159回答 2
2回答

慕无忌1623718

在 Go 中,字符串值是read-only字节切片,您无法更改其元素(不可变)。由于它是一个切片,因此意味着它有一个已定义容量的支持(底层)数组。话虽这么说,我们可以说字符串是一个指向只读后备数组的数据结构。字符串针对高可重用性进行了优化,因此是只读的。每当您修改字符串时,都会在后台创建一个新字符串(字节切片),这使得操作成本较高。一项建议是将字符串转换为实际的字节切片[]byte(string)并使用字节,或者当程序需要执行大量字符串操作时使用strings.Builder 。s := "Hello" // backing array for "hello" created; `s` points to the backing arrayt := 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 arrayt += "There" // `t` was still pointing to "Hello" and with this operation, a new backing array is created for "HelloThere" and `t` points to it

喵喵时光机

经过评论部分对此进行了大量辩论/讨论后,这是我的结论。Golang 没有写时复制。这里的+=是显式创建一个新字符串,相当于s = s + "World"创建一个新字符串并将其分配回s如果你尝试编写以下代码,由于 Golang 字符串的不可变性,将会导致编译错误t[0] = 'A' // cannot assign to t[0]因此,Golang 中的所有内容都是显式的,Golang 没有隐式执行任何操作。这就是 Golang 中不存在写时复制的原因。注意:COW 和不变性并不相互排斥。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go