Je ne comprends pas pourquoi cela ne se compile pas avec:
assertion de type impossible: Faz n'implémente pas Foo (la méthode Bar a un récepteur de pointeur)
si je fais du récepteur pour Faz.Bar une valeur Faz plutôt qu'un pointeur Faz alors il se compile bien, mais j'ai pensé qu'il était toujours préférable d'avoir des récepteurs de pointeur pour que les valeurs ne soient pas copiées?
package main
import (
"log"
)
func main() {
foo := New().(Faz)
log.Println(foo)
}
type Foo interface {
Bar() string
}
func New() Foo {
return &Faz{}
}
type Faz struct {
}
func (f *Faz) Bar() string {
return `Bar`
}
Parce que c'est *Faz
pas Faz
.
func main() {
foo := New().(*Faz)
log.Println(foo)
}
Je pense que la réponse à cette question nécessite une approche plus rétrospective de la grammaire et comment la mettre en œuvre à travers le génie logiciel. (Excusez la simplification excessive)
D'abord un flashback rapide de ce que sont types
?
Ce ne sont que des blocs de mémoire avec la logique du compilateur en haut. Ce qui rend un array
différent d'un string
, c'est ce que le compilateur nous permet de faire avec ces blocs de mémoire. (Pensez plus profondément et vous pourrez commencer à réaliser la vraie différence entre les langues strongly typed
Et dynamically typed
.)
Maintenant, vous devez vous rendre compte que les pointeurs sont leurs propres types.*variable
Est un bloc de mémoire (type aka) différent de variable
. C'est juste que le compilateur suppose toujours que le contenu de *variable
Sera toujours une adresse vers un bloc de mémoire de type à droite de la déclaration avec d'autres restrictions/fonctionnalités qu'il impose.
Récapitulons ensuite ce qu'est une interface.
Définition pseudo-scientifique : Un ensemble d'exigences pour tout citoyen de première classe pour être d'un type spécifique. Traduit en génie logiciel - tout bloc de mémoire (types) qui a la même structure de mémoire (repensez à emballage de la structure) associé à celui-ci comme décrit dans un contrat (interface
) peut être transmis comme avec le nom de type que le contrat mentionne.
Vous pouvez maintenant commencer à réaliser que lorsque vous dites
func (f *Faz) Bar() string
est le bloc de mémoire de f
contenant une fonction, où le type de f
est un pointeur vers Faz
où les zones
func (f Faz) Bar() string
est le bloc de mémoire de f
, où le type de f
est Faz
Ainsi, lorsque vous dites qu'une variable de type *Faz
Satisfait un contrat, comment pouvez-vous supposer qu'une variable de type Faz
sera qualifiée de type d'interface dans le code? Choisissez qui satisfait votre contrat et seul ce type peut assumer le type d'interface dans votre code.