Что из себя представляет тип данных string в языке Golang? Можно ли изменить определенный символ в строке? Что происходит при склеивании строк?go-16

Что представляет собой string в Go?

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

Ключевые особенности:

  • Строки в Go — это значения (value type), а не ссылочные типы.
  • Под капотом строка представлена как структура:
    type stringStruct struct {
      str unsafe.Pointer  // указатель на массив байт
      len int             // длина строки в байтах
    }
    
  • Строки могут содержать нулевые байты (\x00), так как длина хранится отдельно.
  • Поскольку строки неизменяемы, они безопасны для использования в конкурентных операциях.

Можно ли изменить определенный символ в строке?

Нет, строки в Go неизменяемы. Попытка изменить отдельный символ приведет к ошибке компиляции:

s := "hello"
s[0] = 'H' // ошибка: cannot assign to s[0]

Однако можно:

  1. Преобразовать строку в []byte (для ASCII-символов) или []rune (для Unicode), изменить и преобразовать обратно:
    s := "hello"
    bytes := []byte(s)
    bytes[0] = 'H'
    s = string(bytes) // "Hello"
    
  2. Создать новую строку на основе существующей с нужными изменениями.

Что происходит при склеивании строк?

При конкатенации строк (+ или fmt.Sprintf) происходит аллокация новой памяти и копирование содержимого всех строк. Это может быть неэффективно при частых операциях.

Примеры:

s1 := "Hello"
s2 := "World"
result := s1 + " " + s2  // создается новая строка

Для эффективного соединения многих строк лучше использовать strings.Builder:

var builder strings.Builder
builder.WriteString("Hello")
builder.WriteString(" ")
builder.WriteString("World")
result := builder.String()  // более эффективно

Оптимизация компилятора: В простых случаях (конкатенация литералов или небольшого числа строк) компилятор может оптимизировать операцию.

Внутреннее представление конкатенации

При каждой конкатенации:

  1. Выделяется новый участок памяти достаточного размера
  2. Копируется содержимое всех строк-операндов
  3. Старые строки остаются в памяти (до сборки мусора)

Резюмируем

  1. Строки в Go — неизменяемые последовательности байт, обычно UTF-8
  2. Изменить символ в существующей строке нельзя — нужно создавать новую
  3. Конкатенация создает новые строки, что требует аллокации памяти
  4. Для частых модификаций используйте []byte или strings.Builder
  5. Строки безопасны для конкурентного доступа благодаря неизменяемости