Właśnie pracuję nad trasą Go i jestem zdezorientowany co do wskaźników i interfejsów. Dlaczego ten kod Go nie kompiluje się?
package main
type Interface interface {}
type Struct struct {}
func main() {
var ps *Struct
var pi *Interface
pi = ps
_, _ = pi, ps
}
tj. jeśli Struct
jest Interface
, to dlaczego nie *Struct
byłoby a *Interface
?
Otrzymuję komunikat o błędzie:
prog.go:10: cannot use ps (type *Struct) as type *Interface in assignment:
*Interface is pointer to interface, not interface
func main() { var ps *Struct = new(Struct) var pi *Interface var i Interface i = ps pi = &i fmt.Printf("%v, %v, %v\n", *ps, pi, &i) i = *ps fmt.Printf("%v, %v, %v\n", *ps, pi, i) _, _, _ = i, pi, ps }
i tworzenie własnych konkluzjiOdpowiedzi:
Kiedy masz strukturę implementującą interfejs, wskaźnik do tej struktury automatycznie implementuje również ten interfejs. Dlatego nigdy nie masz
*SomeInterface
w prototypie funkcji, ponieważ to by niczego nie dodałoSomeInterface
i nie potrzebujesz takiego typu w deklaracji zmiennej (zobacz to powiązane pytanie ).Wartość interfejsu nie jest wartością konkretnej struktury (ponieważ ma zmienny rozmiar, nie byłoby to możliwe), ale jest rodzajem wskaźnika (dokładniej jest wskaźnikiem do struktury i wskaźnikiem do typu ). Russ Cox opisuje to dokładnie tutaj :
Dlatego właśnie
Interface
, a nie,*Interface
jest prawidłowym typem do przechowywania wskaźnika do implementacji strukturyInterface
.Musisz więc po prostu użyć
źródło
var pi *Interface
.*SomeInterface
nie jest to po prostu błąd kompilacji?Być może to miałeś na myśli:
Kompiluje się OK. Zobacz także tutaj .
źródło
Oto bardzo prosty sposób przypisania struktury do interfejsu:
https://play.golang.org/p/BRTaTA5AG0S
źródło
Używam następującego sposobu,
interface{}
podczas gdy po prostu konsumujęeventsI interface{}
jako argumenty, nadal jestem w stanie wysłać wskaźniki Struct, jak widać poniżej.main.go
Teraz wewnątrz
storyboard.go
pliku Create functionJak widać powyżej, Storyboard.go zużywa tylko,
Events []interface{}
ale w rzeczywistości wysyłam wskaźnik Struct i działa dobrze.kolejny przykład tutaj
źródło