Выбор того, использовать ли получатель значения (value receiver) или получатель указателя (pointer receiver) в методах, может быть трудным, особенно для новых программистов на Go. В случае сомнений используйте указатель, но бывают случаи, когда получатель значения имеет смысл, обычно по соображениям эффективности, например, для небольших неизменяющихся структур или значений базового типа. Вот некоторые полезные рекомендации:
- Если получателем является карта, func или chan, не используйте указатель на них. Если получатель является срезом (slice), а метод не срезает и не перераспределяет срез, не используйте указатель на него.
- Если метод должен изменять получатель, получатель должен быть указателем.
- Если получатель является структурой, которая содержит sync.Mutex или подобное поле синхронизации, получатель должен быть указателем, чтобы избежать копирования.
- Если получатель является большой структурой или массивом, указатель получателя является более эффективным. Насколько большой структурой или массивом? Предположим, что это эквивалентно передаче всех его элементов в качестве аргументов методу. Если он кажется слишком большим, он также слишком велик для получателя.
- Могут ли функции или методы, одновременно или при вызове из этого метода, изменять получателя? Тип значения создает копию получателя при вызове метода, поэтому внешние обновления не будут применяться к этому получателю. Если изменения должны быть видны в исходном получателе, получатель должен быть указателем.
- Если получатель является структурой, массивом или срезом (slice) и любой из его элементов является указателем на что-то, что может изменяться, предпочтите получатель указателя, поскольку это сделает намерение более понятным для читателя.
- Если получатель представляет собой небольшой массив или структуру, которая, естественно, является типом значения (получатель значения) (например, что-то типа time.Time), без изменяемых полей и указателей, или является простым базовым типом, таким как int или string, получатель значения имеет смысл. Получатель значения может уменьшить количество мусора, который может быть сгенерирован; если значение передается в метод значения, вместо размещения в куче (heap) может использоваться копия в стеке (stack). (Компилятор старается избегать этого выделения, но не всегда может быть успешным.) Не выбирайте тип получателя значения по этой причине без предварительного профилирования.
- Наконец, если есть сомнения, используйте получатель указателя.
Читайте также:
- Go Code Review Comments: введение, gofmt
- Эффективный Go: методы - указатели и значения
- Эффективный Go
Комментариев нет:
Отправить комментарий