Каковы ключевые особенности работы со строками в Go?

Ответ

В Go строки представляют собой неизменяемые (immutable) последовательности байт, как правило, в кодировке UTF-8. Это порождает несколько ключевых особенностей:

  1. Представление в памяти и len(): Под капотом строка — это срез байт ([]byte). Поэтому len("Привет") вернёт 12 (по 2 байта на каждый кириллический символ), а не 6. Для подсчёта реального количества символов (рун) используется пакет unicode/utf8:

    import "unicode/utf8"
    
    count := utf8.RuneCountInString("Привет") // вернёт 6
  2. Иммутабельность: Нельзя изменить символ в существующей строке. Любая модификация (например, конкатенация) создаёт новую строку в памяти.

    s := "hello"
    // s[0] = 'H' // Ошибка компиляции!
    s = "H" + s[1:] // Правильно: создается новая строка
  3. Работа с Unicode (руны): Для корректной итерации по символам (а не байтам) используется цикл for ... range, который работает с типом rune (алиас для int32).

    for i, r := range "Привет" {
        fmt.Printf("байт %d: символ %cn", i, r)
    }
  4. Эффективная конкатенация: Из-за иммутабельности многократное сложение строк через оператор + неэффективно, так как на каждой итерации создаётся новый объект и копируются данные. Для таких задач следует использовать strings.Builder.

    var builder strings.Builder
    builder.WriteString("Hello,")
    builder.WriteString(" World!")
    result := builder.String() // Эффективно, без лишних аллокаций
  5. Конвертация: Строки легко и эффективно конвертируются в срез байт ([]byte) и обратно без копирования данных (при соблюдении определенных условий).

    b := []byte("test")
    s := string(b)