Sobes.tech
Middle

What nuances exist when iterating over a string in Go?

sobes.tech AI

Answer from AI

When iterating over a string in Go, it is important to remember that the string is a sequence of bytes, not Unicode characters. The unicode/utf8 package provides functions for working with multi-byte UTF-8 sequences.

Main nuances:

  • Iteration over bytes: The loop for i := 0; i < len(s); i++ iterates over individual bytes. If the string contains multi-byte characters, one character may be represented by multiple bytes.

    // Example of iterating over bytes
    str := "Привет"
    for i := 0; i < len(str); i++ {
        println(str[i]) // outputs bytes, not characters
    }
    
  • Iteration over runes (Unicode code points): To correctly work with Unicode characters, use the loop for index, ru := range s. It iterates over runes (Unicode code points), handling multi-byte UTF-8 sequences.

    // Example of iterating over runes
    str := "Привет"
    for index, ru := range str {
        println(index, ru) // outputs the index of the rune's start and the rune itself (as int32)
    }
    
  • String length: The function len(s) returns the number of bytes, not the number of runes. To get the number of runes, use utf8.RuneCountInString(s).

    // Example of counting bytes and runes
    str := "Привет"
    println("Length in bytes:", len(str))             // outputs the number of bytes
    println("Length in runes:", utf8.RuneCountInString(str)) // outputs the number of runes
    
  • Index access: Accessing s[i] returns the i-th byte, not the i-th rune. Direct access to runes by index is not provided.

    // Example of byte access
    str := "Привет"
    println(str[0]) // outputs the first byte of the string, not the first rune
    
  • String slices: String slices also operate at the byte level. s[i:j] creates a new byte slice.

    // Example of slicing a string by bytes
    str := "Привет"
    println(str[0:2]) // may output an incorrect sequence if the first two bytes do not form a complete rune
    

For reliable Unicode handling in Go, it is recommended to use iteration over runes (range) and functions from the unicode/utf8 package.