Go Strings and Runes
In Go, strings are read-only slices of bytes. When we talk about "characters," Go uses a concept called a rune.
What is a Rune?
A rune is an alias for int32. It represents a single Unicode character (code point). Since some characters (like '世' or emojis) take up multiple bytes, a simple index like s[i] might only give you a fraction of a character.
Basic Example
| package main
import (
"fmt"
"unicode/utf8"
)
func main() {
// A string with a multi-byte character
const s = "Hello, 世界"
// len() returns the number of BYTES
fmt.Println("Len:", len(s)) // 13
// RuneCountInString returns the number of CHARACTERS
fmt.Println("Rune count:", utf8.RuneCountInString(s)) // 9
// To access characters correctly, we use a range loop
for i, runeValue := range s {
fmt.Printf("%#U starts at byte position %d\n", runeValue, i)
}
}
|
Output:
| U+0048 'H' starts at byte position 0
U+0065 'e' starts at byte position 1
U+006C 'l' starts at byte position 2
U+006C 'l' starts at byte position 3
U+006F 'o' starts at byte position 4
U+002C ',' starts at byte position 5
U+0020 ' ' starts at byte position 6
U+4E16 '世' starts at byte position 7
U+754C '界' starts at byte position 10
|
Key Differences
| Feature |
String Byte (s[i]) |
Rune (rune) |
| Represents |
A single byte (8 bits) |
A Unicode character (32 bits) |
| Best for |
Raw data, ASCII text |
International text, Emojis |
String Operations
Go provides a powerful strings package for common tasks:
| package main
import (
"fmt"
"strings"
)
func main() {
s := "test"
fmt.Println(strings.Contains(s, "es")) // true
fmt.Println(strings.Count(s, "t")) // 2
fmt.Println(strings.HasPrefix(s, "te")) // true
fmt.Println(strings.ToUpper(s)) // TEST
}
|
Important Rule: Immutability
Strings in Go are immutable. You cannot change a character inside a string once it is created.
| s := "hello"
// s[0] = 'H' // This will cause an error
|
To modify a string, you must convert it to a slice of runes or bytes, change it, and convert it back:
| runes := []rune(s)
runes[0] = 'H'
s = string(runes) // "Hello"
|