пятница, 15 марта 2019 г.

Go Code Review Comments: Тип получателя (Receiver Type)

Выбор того, использовать ли получатель значения (value receiver) или получатель указателя (pointer receiver) в методах, может быть трудным, особенно для новых программистов на Go. В случае сомнений используйте указатель, но бывают случаи, когда получатель значения имеет смысл, обычно по соображениям эффективности, например, для небольших неизменяющихся структур или значений базового типа. Вот некоторые полезные рекомендации:

  • Если получателем является карта, func или chan, не используйте указатель на них. Если получатель является срезом (slice), а метод не срезает и не перераспределяет срез, не используйте указатель на него.
  • Если метод должен изменять получатель, получатель должен быть указателем.
  • Если получатель является структурой, которая содержит sync.Mutex или подобное поле синхронизации, получатель должен быть указателем, чтобы избежать копирования.
  • Если получатель является большой структурой или массивом, указатель получателя является более эффективным. Насколько большой структурой или массивом? Предположим, что это эквивалентно передаче всех его элементов в качестве аргументов методу. Если он кажется слишком большим, он также слишком велик для получателя.
  • Могут ли функции или методы, одновременно или при вызове из этого метода, изменять получателя? Тип значения создает копию получателя при вызове метода, поэтому внешние обновления не будут применяться к этому получателю. Если изменения должны быть видны в исходном получателе, получатель должен быть указателем.
  • Если получатель является структурой, массивом или срезом (slice) и любой из его элементов является указателем на что-то, что может изменяться, предпочтите получатель указателя, поскольку это сделает намерение более понятным для читателя.
  • Если получатель представляет собой небольшой массив или структуру, которая, естественно, является типом значения (получатель значения) (например, что-то типа time.Time), без изменяемых полей и указателей, или является простым базовым типом, таким как int или string, получатель значения имеет смысл. Получатель значения может уменьшить количество мусора, который может быть сгенерирован; если значение передается в метод значения, вместо размещения в куче (heap) может использоваться копия в стеке (stack). (Компилятор старается избегать этого выделения, но не всегда может быть успешным.) Не выбирайте тип получателя значения по этой причине без предварительного профилирования.
  • Наконец, если есть сомнения, используйте получатель указателя.

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


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

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