Golang是否会在修改/写入时复制字符串?

After reading the answer on Does Go language use Copy-on-write for strings , I feel the question was not adequately answered.

Given the example below, what is actually happening under the hood?

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
", s, t)
}

output:

HelloWorld HelloThere

The question is when will golang determine there is a need to create a new copy?

In Go, string values are read-only byte slices and you cannot change its elements (immutable). Since it is a slice, it means that it has a backing (underlaying) array that has defined capacity. This being said, we can say that string is a data structure that points to a read-only backing array.

Strings are optimized for high reusability and thus read-only. Whenever you modify a string a new string (byte slice) is created in the background which makes it a bit of costly operation. One recommendation is to convert a string to an actual byte slice []byte(string) and work with bytes or use strings.Builder when your program needs to do a lot of string manipulations.

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 - data structure

String Data Type in GO

After much debate/discussion on the at the comment sections, here is my conclusion.

Golang does not have copy-on-write.

The += here is an explicitly creating a new string which is equivalent to s = s + "World" which creates a new string and assign it back to s

And if you try to write the following code, it will result in compilation error due to immutability of the golang string

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

As a result, everything in golang is explicit, nothing is done implicitly by golang in the background. That is why copy-on-write does not exist in Golang.

Note: COW and immutability are not mutually exclusive.