Sobes.tech
Middle

How are strings implemented in the Go programming language?

sobes.tech AI

Answer from AI

A string in Go is an immutable sequence of bytes.

Key features:

  • Immutability: after creation, a string cannot be changed.
  • Representation: stored as a pointer and length. The pointer points to the first byte of the sequence in memory. Length is the number of bytes.
  • Encoding: strings in Go do not carry encoding information. They are often used to store UTF-8, but can contain any bytes.
  • Iteration over bytes: the for index, value range string loop when iterating over a string returns the index and a rune (int32), not a byte.
  • Iteration over runes: a rune represents a Unicode code point. Go uses UTF-8, so one rune can occupy from 1 to 4 bytes.
  • Getting a substring: the slice operation string[start:end] creates a new string pointing to the same memory segment but with different boundaries.

Examples:

// Declaration and initialization
var s string
s = "Привет" // String literal in Go - a sequence of bytes,
             // usually interpreted as UTF-8

// Length of the string in bytes
byteLength := len(s) // 12, since "П", "р", "и", "в", "е", "т" are multi-byte characters in UTF-8

// Iteration over runes
runeCount := 0
for index, runeValue := range s {
    // index - start index of the rune in bytes
    // runeValue - value of the rune (int32)
    _ = index // placeholder for unused variable
    // fmt.Printf("Index: %d, Rune: %c (U+%04X)\n", index, runeValue, runeValue)
    runeCount++
}
// runeCount will be 6

// Iteration over bytes
byteCount := 0
for i := 0; i < len(s); i++ {
    // s[i] - byte at index i
    _ = s[i] // placeholder
    // fmt.Printf("Byte at index %d: %d\n", i, s[i])
    byteCount++
}
// byteCount will be 12

// Getting a substring (byte slice)
// Important: byte slice may break multi-byte rune
// sub := s[0:5] // This may be an invalid UTF-8 sequence

// Use the strings or unicode/utf8 package for safe rune handling

Comparison with byte slice ([]byte):

Characteristic String []byte
Mutability No Yes
Representation Pointer + Length Pointer + Length + Capacity
Type Built-in primitive Slice (slice)
Usage Immutable text Mutable data (bytes)

Conversion between string and []byte:

// string -> []byte
byteSlice := []byte(s)

// []byte -> string
newString := string(byteSlice)