go / intermediate
Snippet
Handling UTF-8 Text Correctly with Runes
In Go, strings are read-only slices of bytes. UTF-8 characters like emojis or accented letters occupy multiple bytes. Slicing or indexing a string directly accesses raw bytes, which can corrupt multi-byte characters. Go uses the rune type (an alias for int32) to represent a Unicode code point. A range loop over a string automatically decodes UTF-8 into runes, and casting a string to []rune allows correct character-based random access and length calculation.
snippet.go
go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package mainimport "fmt"func main() {text := "Gopher 🚀"fmt.Println("Iterating by byte:")for i := 0; i < len(text); i++ {fmt.Printf("%x ", text[i])}fmt.Println()fmt.Println("Iterating by rune (range loop):")for index, runeVal := range text {fmt.Printf("%d:%q ", index, runeVal)}fmt.Println()runes := []rune(text)fmt.Printf("Sub-string length: %d, Char at index 7: %c\n", len(runes), runes[7])}
Breakdown
1
text := "Gopher 🚀"
Defines a string that contains standard ASCII characters and a multi-byte rocket emoji (which takes 4 bytes).
2
len(text)
Returns the length of the string in bytes (11 bytes), not the number of characters (8 characters).
3
for index, runeVal := range text
The range loop automatically decodes UTF-8 bytes into individual runes and provides their starting byte indices.
4
runes := []rune(text)
Converts the string into a slice of runes. This allocates memory but allows O(1) character-based indexing like runes[7].