Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Неизменяемость строк в Go
Строки в Go являются неизменяемыми (immutable) типами данных. Это ключевое свойство, которое отличает работу со строками от работы с срезами байтов.
Что это значит?
Когда вы создаёте строку, её содержимое зафиксировано и не может быть изменено после создания. Любая операция, которая кажется модификацией строки, фактически создаёт новую строку:
package main
import "fmt"
func main() {
s := "Hello"
// Это ОШИБКА компиляции:
// s[0] = "J" // cannot assign to s[0]
// Вместо этого создаём новую строку:
s = "J" + s[1:] // "Jello"
fmt.Println(s)
}
Почему это важно?
1. Безопасность в многопоточности
- Строки безопасны для одновременного доступа из разных горутин
- Не нужны мьютексы для защиты строк
- Нет data races
2. Производительность кэширования
- Go может кэшировать и переиспользовать строки
- Хэши строк стабильны и могут кэшироваться
- Строки безопасно использовать как ключи в map
3. Предсказуемость
- Функция не может неожиданно изменить переданную ей строку
- Нет побочных эффектов
Практические примеры
// Конкатенация создаёт новую строку
a := "Go"
b := a // b указывает на тот же блок памяти
c := a + " is great" // c — совершенно новая строка
// Срезы строк создают новые строки
s := "Golang"
sub := s[0:2] // "Go" — новая строка
// Преобразование в []byte даёт изменяемый срез
str := "Hello"
bytes := []byte(str)
bytes[0] = "J" // ОК — срез изменяемый
newStr := string(bytes) // "Jello"
Альтернатива: работа с []byte
Если нужна изменяемость, используйте срезы байтов []byte:
// Неизменяемо
s := "Hello"
// Изменяемо
b := []byte("Hello")
b[0] = "J"
fmt.Println(string(b)) // "Jello"
Производительность при частых модификациях
При частых конкатенаций и изменениях используйте strings.Builder:
import "strings"
var buf strings.Builder
for i := 0; i < 1000; i++ {
buf.WriteString("item\n")
}
result := buf.String() // Эффективно