среда, 23 января 2019 г.

Эффективный Go: данные, аллокация с помощью new

Go имеет два примитива для аллокации - встроенные функции new и make. Они делают разные вещи и относятся к разным типам, что может сбивать с толку, но правила просты. Давайте сначала поговорим о new. Это встроенная функция, которая выделяет память, но в отличие от своих однофамильцев в некоторых других языках она не инициализирует память, это только нули. То есть, new(T) выделяет обнуленное хранилище для нового элемента типа T и возвращает его адрес, значение типа *T. В терминологии Go он возвращает указатель на вновь назначенное нулевое значение типа T.

Поскольку память, возвращаемая new, обнуляется, полезно договориться при разработке ваших структур данных, что нулевое значение каждого типа может использоваться без дальнейшей инициализации. Это означает, что пользователь структуры данных может создать ее с помощью new и получить право на работу. Например, документация для bytes.Buffer гласит, что «Нулевое значение для Buffer является пустым буфером, готовым к использованию.» Точно так же sync.Mutex не имеет явного конструктора или метода Init. Вместо этого нулевое значение для sync.Mutex определяется как разблокированный мьютекс.

Свойство "нулевое значение является полезным" работает транзитивно. Рассмотрим следующее объявление типа.

type SyncedBuffer struct {
    lock    sync.Mutex
    buffer  bytes.Buffer
}

Значения типа SyncedBuffer также готовы к использованию сразу после аллокации или просто декларации. В следующем фрагменте будут работать оба p и v правильно без дальнейшей договоренности.

p := new(SyncedBuffer)  // type *SyncedBuffer
var v SyncedBuffer      // type  SyncedBuffer


Читайте также:


Комментариев нет:

Отправить комментарий