Для мене дуже незрозуміло, у якому випадку я б хотів використовувати приймач значення, а не завжди використовувати приймач вказівника.
Щоб скласти резюме з документів:
type T struct {
a int
}
func (tv T) Mv(a int) int { return 0 } // value receiver
func (tp *T) Mp(f float32) float32 { return 1 } // pointer receiver
У документах говорять також «Для таких типів, як основні типів, скибочки і малі структури, значення приймач дуже дешево , тому , якщо семантиці методи не потрібно покажчик, значення приймач є ефективним і ясно.»
Перший момент говорить про те, що це "дуже дешево", але питання більше, чи дешевше він, ніж вказівник приймача. Тому я зробив невеликий орієнтир (код на суті), який показав мені, що приймач покажчика швидше навіть для структури, що має лише одне рядкове поле. Ось такі результати:
// Struct one empty string property
BenchmarkChangePointerReceiver 2000000000 0.36 ns/op
BenchmarkChangeItValueReceiver 500000000 3.62 ns/op
// Struct one zero int property
BenchmarkChangePointerReceiver 2000000000 0.36 ns/op
BenchmarkChangeItValueReceiver 2000000000 0.36 ns/op
(Редагувати. Зверніть увагу, що другий пункт став недійсним у нових версіях перегляду, дивіться коментарі) .
Другий пункт говорить: "Ефективне і чітке" - це питання смаку, чи не так? Особисто я віддаю перевагу консистенції, використовуючи всюди однаковий спосіб. Ефективність у якому сенсі? ефективність, яка здається, покажчик майже завжди є більш ефективною. Кілька тестових прогонів з одним властивістю int показали мінімальну перевагу приймача значення (діапазон 0,01-0,1 нс / оп)
Чи може хто-небудь розповісти мені випадок, коли приймач значення має сенс більше, ніж приймач вказівника? Або я роблю щось не так у еталоні, чи не помічав інших факторів?