Ответ
В Go все переменные передаются по значению. Однако поведение при передаче зависит от типа данных. Типы в Go можно условно разделить на две категории:
Значимые типы (Value Types):
При присваивании или передаче в функцию создается полная копия данных. Изменение копии не влияет на оригинал.- Примеры:
int
,float
,string
,bool
,struct
,array
.
- Примеры:
Ссылочные типы (Reference Types):
Это типы, которые под капотом содержат указатель на базовую структуру данных. При присваивании или передаче в функцию копируется только этот указатель (или заголовок структуры), а не все данные, на которые он указывает. Таким образом, несколько переменных могут ссылаться на одну и ту же область памяти.К ним относятся:
- Срезы (
[]T
): Структура, содержащая указатель на массив, длину и ёмкость. - Мапы (
map[K]V
): Указатель на хэш-таблицу. - Каналы (
chan T
): Указатель на внутреннюю структуру канала. - *Указатели (`T`)**: Прямой адрес в памяти.
- Функции (
func
): Указатель на код функции. - Интерфейсы (
interface{}
): Содержат информацию о типе и указатель на значение.
- Срезы (
Пример со срезом демонстрирует это поведение:
func modifySlice(s []int) {
// s — это копия структуры среза, но она указывает на тот же базовый массив
s[0] = 100
}
func main() {
originalSlice := []int{1, 2, 3}
modifySlice(originalSlice)
// Изменение видно в оригинальном срезе, так как оба ссылаются на один массив
fmt.Println(originalSlice) // Вывод: [100 2 3]
}
Ключевое отличие: при работе со ссылочными типами вы манипулируете общими данными через разные переменные, в то время как со значимыми типами вы работаете с независимыми копиями.