J'essaie d'écrire une fonction ceci fonctionne comme un charme sauf que Impossible d'utiliser testServer (type * httpest.server) comme type * externestestServer dans l'argument de retour p>
BlockQuote> Je comprends l'erreur, mais je n'ai pas découvert une solution qui me permet de retourner un type polymorphe qui généralise Un type d'interface em> est défini comme un ensemble de signatures de méthodes. P>
blockQuote> Par conséquent, le retour d'une interface simple ne permettra pas aux membres de données directement accessibles. p> p> gettargetserver () code> pour renvoyer un type polymorphique qui a à la fois un élément de données
URL code> et une méthode
fermeture () < / code>. Ce serait une généralisation de
* serveur code> a > retourné de
httpest.newserver () code>
Mais je veux alternativement être capable de retourner un type personnalisé pour lequel ferme () code> est un nop.
ferme () code> est toujours em> un nop. Lorsque je découvre l'erreur indiquée
### ERROR ### CODE> LIGNE afin de renvoyer un serveur code> Clostable code>, je reçois le message d'erreur suivant: P>
* serveur code> p>
note: " Une visite de Go "définit un type d'interface em> comme suit: p>
3 Réponses :
http.server est une structure, vous ne pouvez donc pas renvoyer un objet polymorphe qui généraliste cela. Vous pouvez faire quelque chose d'autre cependant: Vous pouvez ensuite retourner le serveur de votre fonction. P> p>
Bonne réponse. Cela ressemble à l'approche que j'ai initialement pensé que je devrais prendre. C'est un peu volumineux (créant des emballages supplémentaires pour les choses), donc pas ma préférence.
Vous pouvez créer une struct qui a un champ qui est une chaîne url code> et un champ qui correspond à un
fermeture code>
func code>. Le
Fermer code>
FUNC code> peut être implémenté par
ExternatestSserver code> ou
HTTPTEST.SERVER CODE>:
if urlbase, ok := optionals["urlbase"].(string); ok {
extServer := &externalTestServer{URL: urlbase}
return &server{
URL: urlbase,
Close: extServer.Close,
}
}
testServer := httptest.NewServer(newMyServerHandler())
return &server{
URL: testServer.URL,
Close: testServer.Close,
}
Cela semble se comporter exactement comme je l'avais espéré - et très simple à construire.
N'ayez même pas besoin externestestSserver code> - peut simplement utiliser
Fermer: FUNC () {} code> pour créer le NOP.
L'approche de Chris Drew est idéale pour ce cas particulier, car elle nécessite une surcharge de code minimale. Mettez un autre moyen, c'est la chose la plus simple qui résoudra le problème d'aujourd'hui. La solution utilise la magie d'une fermeture implicite (pour le récepteur em>) pour référencer la mise en oeuvre de ma version légèrement simplifiée de celle-ci est ici. .. p> par l'intégration em> un type d'interface em> dans la structure de retour, ce concept peut être de manière transparente étendu à de mieux supporter des interfaces polymorphes non triviales. Dans ce cas, le polymorphisme est explicite sur la base de l'utilisation interne d'un type d'interface. Néanmoins, le type retourné est une enveloppe comprenant une copie des données de membre (constante), de sorte que l'utilisation est identique - généralisant efficacement celui de fermer () code> polymorphiquement.
* SERVER CODE>
pour ce cas d'utilisation. P> type Server interface {
Close()
}
type nopServer struct {
}
func (nopServer) Close() {}
type genericServer struct {
URL string // snapshot of specific data
Server // embedded interface type for explicit polymorphism
}
func getTargetServer() genericServer {
if urlbase, ok := optionals["urlbase"].(string); ok {
return genericServer{URL: urlbase, Server: nopServer{}}
}
testServer := httptest.NewServer(newMyServerHandler())
return genericServer{URL: testServer.URL, Server: testServer}
}
La seule forme de polymorphisme dans Go est des interfaces et des interfaces décrivent uniquement le comportement; ils ne peuvent pas avoir de champs.
Reddit: Interface vs struct avec les pointeurs de fonction
-2: À ce rythme, je ne deviendrai jamais "curieux" :(