Ответ
Встроенная функция make используется для инициализации и выделения памяти только для трёх встроенных типов:
-
Срезы (slices):
make([]T, len, cap)Создаёт срез, выделяя память под базовый массив и инициализируя дескриптор среза (указатель, длину и ёмкость).s := make([]int, 5, 10) // len=5, cap=10 -
Карты (maps):
make(map[K]V, initialCapacity)Создаёт и инициализирует хэш-таблицу для хранения пар ключ-значение.m := make(map[string]int, 100) -
Каналы (channels):
make(chan T, bufferSize)Создаёт канал для коммуникации между горутинами и, если указано, выделяет буфер.ch := make(chan int, 10)
Ключевое отличие make от new
| Характеристика | make(T, ...) |
new(T) |
|---|---|---|
| Назначение | Инициализация срезов, карт и каналов | Выделение памяти для любого типа |
| Возвращаемое значение | Значение типа T (например, []int) |
Указатель на тип *T (например, *int) |
| Результат | Возвращает инициализированный, готовый к использованию объект | Возвращает указатель на обнулённую (zeroed) область памяти |
Итог: make создаёт и настраивает сложные внутренние структуры (хэш-таблицы, буферы), а new просто выделяет "сырую" обнулённую память и возвращает указатель на неё.
Ответ 18+ 🔞
А, блядь, вот эта тема про make и new — классика, вечный источник путаницы для новичков, которые только начинают в Go лезть. Слушай, сейчас разжуёшь, как кот сука собака.
Короче, make — это не какой-то универсальный инструмент, ёпта. Это спецсредство, как отмычка для трёх конкретных замков. И замки эти — срезы, карты и каналы. Всё! Больше ни на что он не способен, пизда с ушами.
Зачем он? А затем, что эти три штуки — они не простые, у них внутри сложная механика, им перед работой движок завести надо. make как раз этот движок и заводит: память выделяет, внутренние структуры инициализирует, чтоб сразу в дело можно было.
Вот смотри, как это выглядит вживую:
-
Срез (slice):
make([]int, 5, 10)Тут он тебе не просто память под массив выделит. Он создаст этот массив на 10 ячеек, потом сделает дескриптор среза (указатель, длину, ёмкость), нацелит его на массив и скажет: «Вот, длина у тебя пока 5, но можешь расти до 10, не парься». Готовый к работе инструмент, а не просто кусок памяти. -
Карта (map):
make(map[string]int, 100)Тут вообще магия. Он не просто ящик под пары ключ-значение выделит. Он построит целую хеш-таблицу, ёбушки-воробушки, со всеми бакетами и алгоритмами поиска. Указание100— это намёк системе: «Готовься, я планирую где-то столько пар пихать, не тормози потом». -
Канал (channel):
make(chan int, 10)А это вообще для межгорутинного общения. Он создаёт эту трубу для данных и, если надо, буфер к ней прикручивает на 10 сообщений. Безmakeканал — это просто концепция, а с ним — уже работающий механизм синхронизации.
А в чём, блядь, разница с new? Вот тут собака зарыта!
Это два разных зверя, а их постоянно путают. Смотри таблицу, чтобы в голове не каша была:
| Признак | make(T, ...) |
new(T) |
|---|---|---|
| Что делает? | Создаёт и настраивает срезы, карты, каналы. | Выделяет обнулённую память для чего угодно и даёт на неё указатель. |
| Что вернёт? | Готовый объект типа T (например, []int). |
Указатель *T на пустую память (например, *int). |
| Состояние? | Инициализирован, можно сразу юзать. | Zero-value (нули, nil). Карта или канал от new — бесполезны. |
Проще говоря: new — это как получить пустой картонный ящик от завода. make — это как привезти из IKEA шкаф, но уже собранный, с полочками и дверцами на петлях, осталось только вещи разложить.
Вот и весь сказ, блядь. make — для сложной внутренней кухни трёх типов, new — для простого выделения памяти под что попало. Запомни это, и волнение ебать исчезнет.