Вопрос проверяет понимание неизменяемости строк в Go и механизма работы с памятью, что важно для написания эффективного кода.
В Go строки являются неизменяемыми (immutable) типами данных. Это фундаментальное свойство, заложенное в дизайн языка. Когда вы создаёте строку, она размещается в памяти, и её содержимое не может быть изменено. Любая операция, которая на первый взгляд модифицирует строку, на самом деле создаёт новую строку в новом участке памяти.
Основные причины:
Рассмотрим пример:
package main
import "fmt"
func main() {
s := "hello"
fmt.Printf("%p\n", &s) // адрес переменной s
s = s + " world"
fmt.Printf("%p\n", &s) // адрес переменной s (тот же)
// Но сама строка теперь указывает на новую область памяти
}В этом примере переменная s остаётся той же, но её значение (указатель на данные строки) меняется. Старая строка "hello" остаётся в памяти до тех пор, пока сборщик мусора не освободит её.
Строка в Go — это структура из двух полей: указатель на массив байтов и длина. При создании новой строки выделяется новый массив байтов, и указатель в структуре строки обновляется.
type string struct {
Data uintptr // указатель на данные
Len int // длина строки
}Неизменяемость строк в Go — это осознанный компромисс между производительностью и безопасностью. Хотя каждая "модификация" строки требует выделения новой памяти, это делает код более надёжным и предсказуемым, особенно в многопоточных приложениях. Для частых изменений строк рекомендуется использовать strings.Builder или bytes.Buffer, которые работают с изменяемыми буферами.