← Назад к вопросам

Что означает неизменяемость строки?

1.6 Junior🔥 171 комментариев
#Основы Go

Комментарии (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() // Эффективно
Что означает неизменяемость строки? | PrepBro