How can I iterate over a string by runes in Go?

StringLoopsGoRune

String Problem Overview


I wanted to this:

for i := 0; i < len(str); i++ {
    dosomethingwithrune(str[i]) // takes a rune
}

But it turns out that str[i] has type byte (uint8) rather than rune.

How can I iterate over the string by runes rather than bytes?

String Solutions


Solution 1 - String

See this example from Effective Go :

for pos, char := range "日本語" {
    fmt.Printf("character %c starts at byte position %d\n", char, pos)
}

This prints :

character 日 starts at byte position 0
character 本 starts at byte position 3
character 語 starts at byte position 6

> For strings, the range does more work for you, breaking out individual > Unicode code points by parsing the UTF-8.

Solution 2 - String

To mirror an example given at golang.org, Go allows you to easily convert a string to a slice of runes and then iterate over that, just like you wanted to originally:

runes := []rune("Hello, 世界")
for i := 0; i < len(runes) ; i++ {
	fmt.Printf("Rune %v is '%c'\n", i, runes[i])
}

Of course, we could also use a range operator like in the other examples here, but this more closely follows your original syntax. In any case, this will output:

Rune 0 is 'H'
Rune 1 is 'e'
Rune 2 is 'l'
Rune 3 is 'l'
Rune 4 is 'o'
Rune 5 is ','
Rune 6 is ' '
Rune 7 is '世'
Rune 8 is '界'

Note that since the rune type is an alias for int32, we must use %c instead of the usual %v in the Printf statement, or we will see the integer representation of the Unicode code point (see A Tour of Go).

Solution 3 - String

For example:

package main

import "fmt"

func main() {
        for i, rune := range "Hello, 世界" {
                fmt.Printf("%d: %c\n", i, rune)
        }
}

Playground


Output:

0: H
1: e
2: l
3: l
4: o
5: ,
6:  
7: 世
10: 界

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMattView Question on Stackoverflow
Solution 1 - StringDenys SéguretView Answer on Stackoverflow
Solution 2 - StringJustin KulikauskasView Answer on Stackoverflow
Solution 3 - StringzzzzView Answer on Stackoverflow