Golang et à l'héritage
Je veux fournir une base struct avec des méthodes dans ma bibliothèque qui peut être "étendu".
Les méthodes de cette base struct s'appuyer sur des méthodes de l'extension de struct.
Ce n'est pas possible directement en Aller, parce que struct méthodes n'ont accès qu'à leurs structures propres champs, pas de parent des structures.
Le point est d'avoir une fonctionnalité que je n'ai pas à le répéter dans chaque classe étendue.
Je suis venu avec ce modèle, qui fonctionne très bien,
mais c'est très compliquée en raison de sa structure cyclique.
Je n'ai jamais rien trouvé de tel dans les autres Aller au code.
Est ce de l'onu-aller?
Quelle approche différente pourrait-je prendre?
type MyInterface interface {
SomeMethod(string)
OtherMethod(string)
}
type Base struct{
B MyInterface
}
func (b *Base) SomeMethod(x string) {
b.B.OtherMethod(x)
}
type Extender struct {
Base
}
func (b *Extender) OtherMethod(x string) {
//Do something...
}
func NewExtender() *Extender {
e := Extender{}
e.Base.B = &e
return &e
}
- Il est difficile de dire ce que vous faites à partir d'un exemple générique, mais ce n'est pas idiomatique Aller de code. En général, vous devez éviter de penser à des solutions via les classes et l'héritage tout à fait. Utiliser la composition à votre avantage, et n'oubliez pas que tout ne doit pas être une structure représentée par une interface, parfois les fonctions sont tout ce que vous devez.
- Revoir la conception de votre solution. Go a pas d'héritage. Essayer de remodeler l'héritage avec ce Go offre plus probable sera un échec.
- Ne comprends pas pourquoi vous êtes downvoted; vous demandé si c'était une approche appropriée, et si non, ce que vous pourriez faire pour l'améliorer. Au risque de ressembler à un drôle de type, je pense que votre question est bien. Avec cela étant dit, les deux commentateurs ci-dessus m'a frappé sur place.
- Votre exemple de code me confond. Vous voulez probablement seulement pour définir les méthodes de " sur un seul type et de l'intégrer dans les types que vous voulez offrir à ces méthodes. Vous avez dit que vous avez eu un problème", car struct méthodes n'ont accès qu'à leurs structures propres champs", mais ce n'est pas vraiment vrai. Si vous incorporez un peu de type
Base
à l'intérieur de typesA
etB
ensuite, ils peuvent accéder à un exporté champ pourBase
à l'intérieur de leurs méthodes directement. SiBase
a une méthodeOne
et vous souhaitez la remplacer, vous pouvez la redéfinir dansA
et toujours appelerA.Base.One()
dans ce contexte, comme vous le feriez dans les langages à objets. - Je pense que vous avez besoin pour donner un exemple plus concret de ce que vous êtes en train de faire et pourquoi vous pensez que cette approche est nécessaire. Je vous ai donné un upvote pour neutraliser la note car je suis d'accord avec @william.taylor.09.
- vous avez besoin struct intégration de la fonctionnalité de golang. cochez cette stackoverflow.com/questions/32125832/... voter si vous aimez la réponse.
Vous devez vous connecter pour publier un commentaire.
Comme mentionné dans les commentaires, Allez encourage la composition au cours de l'héritage.
À répondre à votre question au sujet de la réduction de la duplication de code, vous pouvez utiliser l'incorporation de.
À l'aide de l'exemple de Efficace Aller ci-dessus, vous commencez avec très étroite des interfaces qui ne font que peu de choses:
Ensuite, vous pouvez soit composer les interfaces dans une autre interface:
Il fonctionne de la même façon pour les structures, où vous pouvez composer des structures qui mettent en œuvre Lecteur et l'Écrivain dans une autre structure:
En gros, tout ce qui implémente un
Reader
ou unWriter
peut être réutilisé pour composer ensemble dans une structure, et que l'extérieur struct va automatiquement mettre en œuvre lesReadWriter
interface.C'est essentiellement faire L'Injection De Dépendance, et c'est super utile pour les tests.
Exemple de la structure de code ci-dessus:
Une chose à noter c'est légèrement différent dans d'autres langues de la composition du paradigme, c'est que le
MyReadWriter
struct pouvez maintenant agir à la fois comme unReader
et unWriter
. C'est pourquoi, dansDoCrazyStuff()
nous nerw.Read(data)
au lieu derw.Reader.Read(data)
.Mise à JOUR: correction d'un exemple incorrect.
MyReadWriter
devrait pas être à l'aide de pointeurs vers des interfaces, mais devrait plutôt êtretype MyReadWriter struct { Reader, Writer }
. Qui permet (par exemple)rw := MyReadWriter{ strings.NewReader("foo"), new(bytes.Buffer) }
.io.Reader
etio.Writer
qui sont des interfaces (et il y a aussi unio.ReadWriter
). Le plus tard, c'est de montrer*bufio.Reader
et*bufio.Writer
qui sont (les deux pointeurs vers des struct types) étant incorporé dans un type de mettre en œuvreio.ReadWriter
. Ces deux extraits proviennent de différents paquets, et vous ne pouvez pas simplement cut-n-collez-les ensemble.Désolé de vous décevoir, mais vous poser la mauvaise question. J'ai eu un problème similaire quand j'ai commencé à écrire, Aller au code.
Vous ne pouvez pas simplement prendre une hiérarchie de classes et de le traduire pour Aller au code, du moins pas avec des résultats satisfaisants. Habituellement, il est un très élégant et simple pour résoudre ce genre de choses en Aller, mais pour les découvrir, vous avez besoin de penser un peu différemment que vous êtes habitué à.
Malheureusement, votre question ne dit rien sur le ce problème que vous essayez de résoudre. Vous venez de décrire comment vous souhaitez résoudre. Donc je suis un peu réticent à donner une réponse générale, car il ne sera pas conduire à idiomatiques Aller de code. Je comprends, si vous êtes déçu par cette réponse, mais à mon avis, c'est le plus de valeur en mesure de répondre, vous pouvez obtenir 🙂