Go

How are strings represented in Go? What does this print?

Question 11MediumGo 1.22 to 1.25
s := "héllo"
fmt.Println(len(s))
fmt.Println(s[1])
fmt.Println(utf8.RuneCountInString(s))
for i, r := range s {
	fmt.Printf("%d:%c ", i, r)
}

Output:

6
195
5
0:h 1:é 3:l 4:l 5:o

A string is an immutable, read-only sequence of bytes. Under the hood it's a two-word header: a pointer to the data and a length. The bytes don't have to be valid UTF-8, but source code literals are UTF-8. len counts bytes, and "é" takes 2 bytes (0xC3 0xA9). Indexing, s[1], gives a byte (uint8), here 195. A for range loop over a string decodes UTF-8. It yields the byte offset where each rune starts, together with the rune (int32), which is why index 2 is skipped.

Key points:

  • s[i] = 'x' doesn't compile, because strings are immutable. Convert to []byte or []rune to change one.
  • Slicing, s[1:3], works on byte offsets and can cut a multi-byte character in half.
  • To reverse text or get the n-th character, convert to []rune. For graphemes like emoji with modifiers, you need a library such as golang.org/x/text or rivo/uniseg.

More on Language Fundamentals & Types

All 39 Language Fundamentals & Types questions