Puntatori a un'Interfaccia
Quasi mai hai bisogno di puntatori a tipi di interfaccia. Dovresti passare le interfacce per valore e, in questo modo, i dati sottostanti passati possono comunque essere un puntatore.
Le interfacce sono essenzialmente rappresentate con due campi a livello sottostante:
- Un puntatore a informazioni su un tipo specifico. Puoi pensarci come "il tipo".
- Un puntatore ai dati. Se i dati memorizzati sono un puntatore, sono memorizzati direttamente. Se i dati memorizzati sono un valore, viene memorizzato un puntatore a quel valore.
Se vuoi che i metodi dell'interfaccia modificano i dati sottostanti, devi utilizzare i receiver puntatore (assegnare il puntatore dell'oggetto alla variabile dell'interfaccia).
type F interface {
f()
}
type S1 struct{}
func (s S1) f() {}
type S2 struct{}
func (s *S2) f() {}
// f1.f() non può modificare i dati sottostanti
// f2.f() può modificare i dati sottostanti, il puntatore dell'oggetto è assegnato alla variabile dell'interfaccia f2
var f1 F = S1{}
var f2 F = &S2{}
Non usare mai puntatori a un'interfaccia, è privo di significato. Nel linguaggio Go, l'interfaccia stessa è un tipo di riferimento. In altre parole, il tipo di interfaccia stesso è un puntatore. Per le mie esigenze, il parametro per il testing ha solo bisogno di essere myinterface, e ho solo bisogno di passare un tipo *mystruct (e posso passare solo un tipo *mystruct) quando passo il valore.
type myinterface interface{
print()
}
func test(value *myinterface){
//qualcosa da fare ...
}
type mystruct struct {
i int
}
// Implementa l'interfaccia
func (this *mystruct) print(){
fmt.Println(this.i)
this.i=1
}
func main(){
m := &mystruct{0}
test(m) // Sbagliato
test(*m) // Sbagliato
}