go - 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 中,字符串值是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
推荐阅读
- android - Android Jetpack Navigation 组件可以处理片段中的后退操作吗?
- reactjs - 传递参数以响应本机 onPress 事件、应用程序冻结或数据未定义
- javascript - JavaScript 在“每个”循环内部或外部声明函数
- ios - iOS Spotify SDK 中的播放器上下文
- microsoft-graph-api - 如何知道您的应用程序是否被公司屏蔽?
- c# - .NetCore for Mac - 发布到本机 Mac 应用程序/二进制文件?
- r - 为什么即使在 R 中定义了“month.observed”对象,我也找不到它?
- c++ - MPI C++ 你想用每个数字分别对待每个数字
- php - 删除数据库中的值 - PHP
- arrays - 在 python 上重复进程但使用混合变量