As a go developer, you may have heard that strings in go are immutable. But what does that actually mean? It took me a long time to actually understand what this meant, because when working with strings, they certainly feel mutable.

What do you mean strings are immutable? I just mutated it here:

package main

import “fmt”

func main() { msg := “Hello, 世界” fmt.Println(msg)

msg = "Yello, 世界"
fmt.Println(msg)

}

And a quick search for “go immutable strings” will reveal that, I’m not the only developer that was confused by the immutability of strings. https://www.reddit.com/r/golang/comments/57ica9/arent_strings_in_go_immutable/

One important thing to note about strings in golang is that under the hood they are actually represented by a pointer to an array of bytes. When you update a string variable like in the above example, your actually creating a new byte slice and then updating the pointer to reference this new slice. So that’s what we mean when we say that strings are immutable. The underlying memory that holds the string cannot be mutated.

Let’s try to update a character of a string:

// You can edit this code! // Click here and start typing. package main

import “fmt”

func main() { msg := “Hello, 世界” fmt.Println(msg)

msg[0] = 'Y'
fmt.Println(msg)

}

If you try to run the above example, you’ll get an error. And this is what we mean when we say strings are immutable. If we want to change a string, we actually have to create a brand new one and replace the old one. We can’t just edit part of the string.

For me it’s sometimes easier to understand if I see a counter example. What would it look like if strings were mutable? Here’s an example of using []bytes like mutable strings.

package main

import “fmt”

type MutableString []byte

func (s MutableString) String() string { return string(s) }

func main() { msg := MutableString(“Hello, 世界”) fmt.Println(msg)

msg[0] = 'Y'
fmt.Println(msg)

}

In this example you can see that we can update individual letters in the string.