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

Какие знаешь ссылочные типы данных в Golang?

1.0 Junior🔥 231 комментариев
#Основы Go#Производительность и оптимизация

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Ссылочные типы данных в Go

В языке Go существует несколько ссылочных типов данных, которые хранят не сами значения, а адреса в памяти, где эти значения расположены. При присваивании или передаче в функции копируется именно эта ссылка, а не сами данные. Вот основные ссылочные типы в Go:

1. Указатели (Pointers)

Указатели хранят адрес переменной в памяти. Они позволяют работать с данными косвенно, что полезно для модификации исходных значений и оптимизации памяти.

package main

import "fmt"

func main() {
    x := 42
    var p *int = &x  // p хранит адрес x
    fmt.Println(*p)  // 42 (разыменование)
    *p = 100         // Изменяем значение x через указатель
    fmt.Println(x)   // 100
}

2. Срезы (Slices)

Срез — это динамическое представление массива, состоящее из указателя на массив, длины и ёмкости. Все срезы, ссылающиеся на один массив, разделяют его данные.

package main

import "fmt"

func main() {
    arr := [5]int{1, 2, 3, 4, 5}
    s1 := arr[1:4]  // Срез с элементами [2,3,4]
    s2 := s1        // Копируется ссылка на массив!
    s2[0] = 99
    fmt.Println(s1) // [99 3 4]
    fmt.Println(arr) // [1 99 3 4 5]
}

3. Карты (Maps)

Карта — это хэш-таблица, хранящая пары ключ-значение. При присваивании копируется дескриптор карты, а не её содержимое.

package main

import "fmt"

func main() {
    m1 := map[string]int{"a": 1, "b": 2}
    m2 := m1  // m2 ссылается на ту же карту
    m2["c"] = 3
    fmt.Println(m1) // map[a:1 b:2 c:3]
    fmt.Println(m2) // map[a:1 b:2 c:3]
}

4. Каналы (Channels)

Каналы используются для общения между горутинами (goroutines). Они также являются ссылочным типом — несколько переменных могут ссылаться на один канал.

package main

import "fmt"

func main() {
    ch1 := make(chan int, 2)
    ch2 := ch1  // ch2 ссылается на тот же канал
    ch1 <- 42
    fmt.Println(<-ch2) // 42 (читаем из ch2, но данные из общего канала)
}

5. Функции (Functions)

В Go функции — это первоклассные объекты, и их можно присваивать переменным, передавать и возвращать из других функций. Переменные функции содержат ссылку на код функции.

package main

import "fmt"

func greet(name string) {
    fmt.Println("Hello,", name)
}

func main() {
    var f func(string) = greet  // f ссылается на функцию greet
    f("World") // Hello, World
}

6. Интерфейсы (Interfaces)

Интерфейсы хранят динамическую информацию о типе: указатель на конкретные данные и информацию о типе. Это делает их ссылочным типом.

package main

import "fmt"

type Speaker interface {
    Speak() string
}

type Dog struct{}

func (d Dog) Speak() string {
    return "Woof!"
}

func main() {
    var s Speaker = Dog{}
    fmt.Println(s.Speak()) // Woof!
}

Ключевые особенности ссылочных типов в Go

  • Общие данные: При присваивании одного ссылочного типа другому обе переменные ссылаются на одни и те же данные в памяти.
  • Сравнение с nil: Все ссылочные типы можно сравнивать с nil, что означает отсутствие инициализации.
  • Передача в функции: При передаче в функцию копируется только ссылка, что эффективно по памяти, но требует осторожности с мутациями.
  • Сборка мусора: Все ссылочные типы управляются сборщиком мусора Go, который освобождает память, когда на объект больше нет ссылок.

Важные отличия от других языков

В отличие от языков вроде Java или C#, в Go нет классического наследования через ссылки на объекты классов. Вместо этого используется композиция и интерфейсы. Также важно отметить, что сам interface{} (пустой интерфейс) может хранить как ссылочные, так и значимые типы (value types), такие как int, float, struct.

Понимание разницы между ссылочными и значимыми типами критично для написания эффективных и безопасных программ на Go, особенно при работе с параллелизмом и модификацией данных.

Какие знаешь ссылочные типы данных в Golang? | PrepBro