首页 > 解决方案 > Golang 是否在修改/写入时复制字符串?

问题描述

在阅读了Does Go language use Copy-on-write for strings的答案后 ,我觉得这个问题没有得到充分的回答。

鉴于下面的示例,引擎盖下实际发生了什么?

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 什么时候会确定需要创建一个新副本?

标签: go

解决方案


在 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

StringHeader - 数据结构

GO 中的字符串数据类型


推荐阅读