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:

  1. Un puntatore a informazioni su un tipo specifico. Puoi pensarci come "il tipo".
  2. 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
}