Ответ
В Go строки представляют собой неизменяемые (immutable) последовательности байт, как правило, в кодировке UTF-8. Это порождает несколько ключевых особенностей:
-
Представление в памяти и
len()
: Под капотом строка — это срез байт ([]byte
). Поэтомуlen("Привет")
вернёт12
(по 2 байта на каждый кириллический символ), а не6
. Для подсчёта реального количества символов (рун) используется пакетunicode/utf8
:import "unicode/utf8" count := utf8.RuneCountInString("Привет") // вернёт 6
-
Иммутабельность: Нельзя изменить символ в существующей строке. Любая модификация (например, конкатенация) создаёт новую строку в памяти.
s := "hello" // s[0] = 'H' // Ошибка компиляции! s = "H" + s[1:] // Правильно: создается новая строка
-
Работа с Unicode (руны): Для корректной итерации по символам (а не байтам) используется цикл
for ... range
, который работает с типомrune
(алиас дляint32
).for i, r := range "Привет" { fmt.Printf("байт %d: символ %cn", i, r) }
-
Эффективная конкатенация: Из-за иммутабельности многократное сложение строк через оператор
+
неэффективно, так как на каждой итерации создаётся новый объект и копируются данные. Для таких задач следует использоватьstrings.Builder
.var builder strings.Builder builder.WriteString("Hello,") builder.WriteString(" World!") result := builder.String() // Эффективно, без лишних аллокаций
-
Конвертация: Строки легко и эффективно конвертируются в срез байт (
[]byte
) и обратно без копирования данных (при соблюдении определенных условий).b := []byte("test") s := string(b)