Strings and Runes
In this page:
Strings Are Byte Sequences
A Go string is fundamentally an immutable sequence of bytes. For plain ASCII text each byte is one character, but for Unicode text (like emoji or non-Latin scripts) a single character can be encoded as multiple bytes using UTF-8.
Example: Strings Are Byte Sequences
package main
import "fmt"
func main() {
s := "Go"
fmt.Println("bytes:", len(s))
fmt.Println("first byte:", s[0])
}
Login to try C/C++/Java/PHP code in the editor
What Is a Rune?
A rune represents one Unicode code point -- one real, human-perceived character -- regardless of how many bytes it takes to encode in UTF-8. Converting a string to []rune gives you a slice where each element is exactly one character.
Note: rune is just an alias for int32 in Go.
Example: What Is a Rune?
package main
import "fmt"
func main() {
s := "café"
fmt.Println("byte length:", len(s))
fmt.Println("rune length:", len([]rune(s)))
}
Login to try C/C++/Java/PHP code in the editor
Iterating Correctly with for range
Using 'for range' on a string automatically decodes it rune by rune, giving you the correct starting byte index and the full Unicode code point at each step, which correctly handles multi-byte characters instead of splitting them apart.
Note: Never loop with a plain byte index if the string might contain non-ASCII characters.
Example: Iterating Correctly with for range
package main
import "fmt"
func main() {
for i, r := range "café" {
fmt.Printf("index %d: %c\n", i, r)
}
}
Login to try C/C++/Java/PHP code in the editor
Strings Are Immutable
Once created, a Go string's contents can never be changed in place -- operations that appear to modify a string, like concatenation, actually produce a brand-new string. To build up text piece by piece efficiently, Go provides strings.Builder.
Example: Strings Are Immutable
package main
import "fmt"
func main() {
s := "Hello"
s = s + ", Go!" // creates a new string, doesn't mutate the old one
fmt.Println(s)
}
Login to try C/C++/Java/PHP code in the editor
- Indexing a string with s[i] expecting a character, when it actually returns a single byte, breaking on multi-byte Unicode characters.
- Using len(s) to count characters when the string contains multi-byte UTF-8 characters -- len returns byte count, not character count.
- Trying to modify a string in place, e.g. s[0] = H, which fails because strings are immutable in Go.
- Go strings are immutable sequences of bytes, usually holding UTF-8 encoded text.
- A rune represents a single Unicode code point (one real character), stored as an int32.
- 'for range' over a string iterates rune by rune, correctly handling multi-byte characters.
- len(s) returns the byte count, not the character count, for non-ASCII strings.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: