Non è molto chiaro per me, nel qual caso vorrei utilizzare un ricevitore di valore invece di usare sempre un ricevitore di puntatore.
Ricapitolando dai documenti:
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
La documentazione dice anche "Per i tipi come i tipi di base, le slice e le piccole strutture, un ricevitore di valore è molto economico, quindi a meno che la semantica del metodo non richieda un puntatore, un ricevitore di valore è efficiente e chiaro."
Primo punto dice che è "molto economico", ma la domanda è più è più economico del ricevitore del puntatore. Così ho fatto un piccolo benchmark (code on gist) che mi ha mostrato che il ricevitore del puntatore è più veloce anche per una struttura che ha un solo campo stringa. Questi sono i risultati:
// 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
(Modifica: si prega di notare che il secondo punto non è più valido nelle versioni go più recenti, vedere i commenti) .
Secondo punto dice, è "efficiente e chiaro" che è più una questione di gusti, non è vero? Personalmente preferisco la coerenza usando ovunque allo stesso modo. Efficienza in che senso? dal punto di vista delle prestazioni sembra che i puntatori siano quasi sempre più efficienti. Poche prove con una proprietà int hanno mostrato un vantaggio minimo del ricevitore Value (intervallo di 0,01-0,1 ns / op)
Qualcuno può dirmi un caso in cui un ricevitore di valore ha chiaramente più senso di un ricevitore di puntatore? O sto facendo qualcosa di sbagliato nel benchmark, ho trascurato altri fattori?