Jest dla mnie bardzo niejasne, w którym przypadku chciałbym użyć odbiornika wartości zamiast zawsze używać odbiornika wskaźnika.
Podsumowując z dokumentów:
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
Plik docs mówi także „Dla typów, takich jak podstawowe typy, plasterki i małych strukturach, odbiornik wartość jest bardzo tanie, więc chyba semantyka metody wymaga wskaźnik, odbiornik wartość jest efektywny i przejrzysty”.
Po pierwsze , mówi, że jest „bardzo tani”, ale pytanie brzmi raczej, czy jest tańszy niż odbiornik wskaźnika. Więc zrobiłem mały test porównawczy (kod w istocie) który pokazał mi, że odbiornik wskaźnika jest szybszy nawet dla struktury, która ma tylko jedno pole tekstowe. Oto wyniki:
// 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
(Edycja: należy pamiętać, że drugi punkt stał się nieważny w nowszych wersjach go, patrz komentarze) .
Drugi punkt mówi, że jest „wydajny i przejrzysty”, co jest bardziej kwestią gustu, prawda? Osobiście wolę spójność, używając wszędzie w ten sam sposób. W jakim sensie efektywność? pod względem wydajności wydaje się, że wskaźniki są prawie zawsze bardziej wydajne. Kilka testów z jedną właściwością int wykazało minimalną przewagę odbiornika wartości (zakres 0,01-0,1 ns / op)
Czy ktoś może mi powiedzieć o przypadku, w którym odbiornik wartości ma wyraźnie większy sens niż odbiornik wskaźnika? A może robię coś źle w teście porównawczym, czy przeoczyłem inne czynniki?