@midia21

Зачем нужны «ссылочные» методы и почему они не удовлетворяют интерфейсам?

Часто вижу что параметры функций, свойства структур в Go передаются как ссылки. В общем то это понятно - читал, что это экономит память + можно сделать проверку на nil для проверки на непереданный параметр. Однако немного смущает когда методы привязывают к структуре через "*":
type Speaker interface {
	Speak()
}

type Human struct {}

func (h *Human) Speak() {

}


Уточню: зачем писать func (h *Human), если можно func (h Human)?

Дополнительный вопрос: немного неясно почему в данном примере Human не будет удовлетворять интерфейсу Speaker (ошибка: missing method Speak (Speak has pointer receiver))? Однако если убрать привязку метода по ссылке - все норм. Заранее спасибо.
  • Вопрос задан
  • 165 просмотров
Решения вопроса 1
func (h *Human) Speak() {

}

Если глянуть на внутренности языка, то метод это по сути обычная функция, у которой первым параметром является ресивер (тот объект, у которого вызывается метод). То есть, компилятор этот код превратит в
func Speak(h *Human) {

}

Соответственно, при вызове метода в случае *Human будет передача структуры по указателю, а в случае Human, по значению, со всеми вытекающими.

Что касается ошибки про несоответствие интерфейсу, то тут надо учесть, что если у структуры определены методы через указатель, то и соответствовать интерфейсу будет указатель на эту структуру: https://go.dev/play/p/o7EsGmeYSRS
Если же без указателя, то соответствовать интерфейсу будет сама структура: https://go.dev/play/p/oTsXP4DXaMJ
Но оба одновременно определить не получится.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
WinPooh32
@WinPooh32
Stack Overflow answer searching expert
*Human и Human это два абсолютно разных типа данных.
Значит и реализацию для интерфейсов для каждого типа надо делать отдельно.

*Human - указатель на значение типа Human.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы