-3
votes

Polymorphisme sans méthodes d'aller

Remarque: je modifie cette question à un exemple concret de la raison pour laquelle je veux faire cela, c'est pourquoi certaines des réponses ne peuvent plus avoir de sens dans le contexte.

J'écris un peu de code qui passe données d'une entrée. Les données se présentent sous la forme de balises qui ont un identifiant de quel type de données qu'ils contiennent, puis les données.

Malheureusement, je n'ai malheureusement pas de contrôle sur l'entrée et je ne sais pas à l'avance, quelles étiquettes seront Il y en a une autre pourrait être une autre chaîne, mais une autre pourrait être une gamme d'INTS.

Le problème se pose lorsque je dois gérer toutes les étiquettes comme du même type, par exemple si j'ai une tranche de balises, d'une fonction accepte ou renvoie une étiquette.

Les solutions que j'ai jusqu'à présent vues à cela consiste à définir les tranches / fonctions avec une interface vide qui me permettrait de le faire Cependant, c'est un peu indésirable car il ne dirait rien aux autres personnes utilisant le paquet sur quels types sont attendus et il défie un peu le point d'avoir une langue typée en premier lieu.

interfaces semble cependant Pour être la solution ici, et j'aimerais avoir une interface tique pour réussir, cela nécessite ce que je définis les méthodes d'eux, et Il n'y a vraiment aucune méthode dont ils ont besoin.

Ma solution actuelle ressemble à ceci xxx

tandis que cela fonctionne et résout mon problème, avoir à définir le mannequin Méthodes Juste pour cela se sent très mal.

Donc, ma question résume-t-elle dans ceci: Y a-t-il un moyen de définir que quelque chose est une balise sans avoir à définir des méthodes factices?


4 commentaires

En utilisant l'interface vide.


Cela vous obligerait à définir une fonction qui a pris un de ceux-ci comme premier argument avec une interface vide comme type. Je suppose que je peux faire cela, mais je préférerais simplement aller avec la Sollution que j'ai posté et retenir un contrôle sur ce qui est passé.


Pourquoi demandes-tu? Pourquoi voulez-vous utiliser une langue strictement typée pour cela?


Version courte: Je charge un tas de balises dans ce type peut être de types différents (je n'ai aucun contrôle sur l'entrée), mais je veux toujours pouvoir dire que "ceci est une liste de balises" ou "cette méthode revient une balise "ou" cette méthode nécessite une étiquette "


3 Réponses :


1
votes

Vous pouvez utiliser [] interface {} pour une "tranche de n'importe quel type", mais elle est à la fois à vous d'utiliser des assertions de type et / ou de type commutateurs pour découvrir les types d'exécution réels de cette tranche Membres.

En savoir plus sur les interfaces vides dans le Tour of Go < HR>

Et maintenant vouloir faire une tranche pouvant contenir à la fois T1 et T2 mais rien sinon.

C'est une exigence assez inhabituelle et il est peu probable que cela ait besoin de cela. Mais vous pouvez également faire votre propre union discriminée avec: xxx

puis utiliser [] élément , vérifier typeelector Runtime pour voir quelle valeur est peuplée.

Vous pouvez même utiliser * t1 et * t2 et avoir nil signifier "Pas de valeur dans ce champ".


5 commentaires

Peut-être qu'un meilleur exemple serait si je veux faire une fonction qui prend un premier argument de ces deux, mais pas d'autre type.


Vous ne pouvez pas faire cela non plus, pour la même raison pour laquelle vous ne pouvez pas le faire avec une tranche.


@Zlug: Encore une fois, vous devez utiliser l'une des méthodes décrites ici. Il n'y a pas d'autre moyen, actuellement pour le faire. Cela dit, il est presque certain que les interfaces devraient vous aider une fois que vous avez reconsidéré un design plus idiomatique.


"Je veux faire une fonction qui prend un premier argument qui est d'Eateau de ces deux, mais pas d'autre type." @zlug Vous pouvez aussi semblable à ce que l'interface et les deux types vivent Leur propre package, exportez le type d'interface mais gardez ses méthodes inexportées, aucun type en dehors de cet emballage ne pourra mettre en œuvre cette interface. Seuls les types qui vivent dans le même package que cette interface pourront la mettre en œuvre.


@mkopriva oui. C'est exactement ce que j'ai fait dans mon exemple. J'espérais juste que je n'avais pas eu à y aller. Merci pour la suggestion cependant.



3
votes

Et maintenant vouloir faire une tranche pouvant contenir à la fois T1 et T2, mais rien d'autre.

Vous ne pouvez pas faire ça. Désolé.


4 commentaires

En supposant que vous commenciez cette ligne spécifique. Je peux le faire. C'est l'utilisation d'interfaces. Question est si je peux le faire sans avoir à définir des méthodes factices.


@Zlug Non, vous ne pouvez littéralement pas. La mise en œuvre de l'interface est implicite en déplacement, de sorte que tout le monde puisse créer un type qui remplit l'interface et qu'il pourrait être inséré dans cette tranche. Vous ne peut pas restreindre une tranche à deux types spécifiques.


Je vois que j'ai choisi les mauvais mots alors. Je suis parfaitement acceptable avec n'importe quelle autre valeur qui remplit l'interface utilisée. Ce que je cherche, c'est un moyen de faire un type de remplir une interface sans avoir à définir une méthode. Ou si une autre façon que les interfaces résout ce problème, je suis totalement acceptable.


"Ce que je cherche, c'est un moyen de faire un type de remplir une interface sans avoir à définir une méthode." @zlug Vous pouvez le faire uniquement avec des types de struct et non avec des intenses, des chaînes, etc. . Vous pouvez le faire en implémentant la méthode une fois sur TYPE X , puis avez les autres types struct incorporer x .



2
votes

Ce que je ferais dans votre scénario est d'accepter tout type dans les paramètres avec une interface vide puis utilisez une affirmation de type à l'intérieur pour confirmer que c'est le type souhaité. XXX

SI Vous voulez que le couplage serré entre un type de données et sa méthode, à savoir un objet, ce qui est tellement faux, avec la méthode de l'objet?


0 commentaires