liveBook · Manning

Rune

As explained in 100 Go Mistakes and How to Avoid Them

A rune is Go's representation of a Unicode code point, implemented as an alias of int32.

A rune is a Unicode code point. In Go, `rune` is an alias of `int32`. Do not confuse a rune with a byte: UTF-8 can encode one code point using multiple bytes. For example, `汉` is one rune but occupies three UTF-8 bytes. section 5.1

A string holds bytes, not a guaranteed sequence of UTF-8 code points. Go string literals are UTF-8, but a string obtained elsewhere can contain arbitrary bytes. Consequently, `len(s)` counts bytes, not runes. section 5.1

s := "hêllo"            #1
for i := range s {
    fmt.Printf("position %d: %c\n", i, s[i])
}
fmt.Printf("len=%d\n", len(s))

This loop visits the starting byte index of each rune, then prints `s[i]`—a byte rather than the rune. In `hêllo`, it prints `Ã` instead of `ê`, skips index 2, and reports a length of 6 for five runes. section 5.2

Choose the operation that matches the index you need:

  • Use `for i, r := range s` to get each rune and the byte index where its encoding starts. Print `r`, not `s[i]`. section 5.2
  • Convert to `[]rune(s)` when you need rune-based indexes or access to a particular rune by position. section 5.2
  • For a UTF-8 string, use `utf8.RuneCountInString(s)` when you need a rune count rather than a byte count. section 5.2
s := "hêllo"
runes := []rune(s)
for i, r := range runes {
    fmt.Printf("position %d: %c\n", i, r)
}
position 0: h
position 1: ê
position 2: l
position 3: l
position 4: o

After conversion to `[]rune`, `hêllo` has indexes 0 through 4; `ê` occupies one position despite its two-byte UTF-8 encoding. section 5.2

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Defines rune and traces incorrect iteration through its output, then compares range values, rune slices, and UTF-8 rune counting.
Examples
Contrasts the three-byte `汉` with loops over `hêllo` that print a byte, a rune, or rune-slice positions.
What it assumes
Assumes familiarity with Go strings, indexing, and range loops while defining charsets, encodings, and code points before using runes.
What you can do after
Diagnose/debug with it: distinguish byte lengths and offsets from rune counts and positions, then select the appropriate iteration or conversion.
How it connects
Connects Unicode code points to UTF-8 encoding, string byte indexes, range iteration, `[]rune`, and `unicode/utf8`.

Also explained in

Compare how 4 books explain rune →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.