2017-09-01 2 views
0

J'ai un modèle comme ce qui suit:Comment convertir une structure qui a une autre structure dans Golang?

type TeamsKey struct { 
    KeyData TeamsKeyData 
    Fingerprint string 
    Algorithm string 
    Encoding string 
    Usage string 
} 

type TeamsKeyData struct { 
    KeyId string 
    Key string 
    Description string 
    ExpiresAt string 
    CreatedAt string 
} 

type Key struct { 
    KeyData  KeyData 
    Fingerprint string 
    Algorithm string 
    Encoding string 
    Usage  string 
} 

type KeyData struct { 
    KeyId  string 
    Key   string 
    Description string 
    ExpiresAt string 
    CreatedAt string 
} 

Je veux convertir une instance de clé de TeamsKey. Bien que la structure sous-jacente soit la même, je ne peux pas la convertir.

func main() { 
    k := Key{} 
    a := TeamsKey(k) 
} 

L'erreur que je suis:

tmp/sandbox251934449/main.go:46:15: cannot convert k (type Key) to type TeamsKey 

Quand je change TeamsKeyData-KeyData en TeamsKey struct, je peux convertir le struct sans problème. La question est la suivante: pourquoi ne puis-je pas convertir les instances les unes aux autres même si la structure sous-jacente est exactement la même?

Merci!

+2

Il ne s'agit pas de la même structure globale, la conversion de type nécessite des types sous-jacents identiques: https://golang.org/ref/spec#Conversions – JimB

+1

Compte tenu de ce scénario, le mieux que vous pouvez faire est d'écrire une fonction qui prend ce type, crée le nouveau, assigne tous les champs manuellement, puis le retourne. Ou refactoriser de sorte que vous n'avez pas deux structures identiques ... juste celui. – RayfenWindspear

+0

@JimB cela signifie-t-il que même si les structures imbriquées ont la même structure sous-jacente (TeamsKeyData et KeyData), il est impossible de convertir une structure en une autre car TeamsKeyData et KeyData ne sont pas du même type? – user2604150

Répondre

1

Lors de la conversion d'un article, il n'est pas suffisant pour eux d'avoir des dispositions identiques, ils need to have the same underlying type for all their fields.

Dans ce cas, le mieux que vous pouvez faire est de faire une nouvelle structure du type que vous voulez et remplir ses champs avec des données de l'ancienne structure. J'ai joué avec certains avec ça, mais je n'ai pas pu faire mieux que ça.

Je suppose que les deux types KeyData nécessitent des ensembles de méthodes différents? Si c'est pas le cas, vous devriez simplement utiliser le même type les deux endroits.

0

Vous ne pouvez pas convertir ou affecter de façon normale des variables de types différents. Mais si c'est nécessaire et que vous êtes certain que les strutures ont la même disposition sous-jacente, vous pouvez omettre la garantie du compilateur et la rendre dangereuse.

import "unsafe" 
... 
a := *((*TeamsKey)(unsafe.Pointer(&k))) 
... 

Il n'est pas recommandé sans raisons sérieuses, vous devriez bien comprendre ce que vous faites.

+0

Personnellement, je ne peux pas tolérer de suggérer à quelqu'un de contourner les types qui ne les comprennent pas complètement. – RayfenWindspear

+0

Alors devrais-je mieux supprimer la réponse? Mais techniquement, nous pouvons le faire. – Uvelichitel

+2

Ajoutez de bons avertissements sur la façon dont ce n'est pas une bonne idée et je vais supprimer le downvote. Le gros problème est que cela causera probablement des paniques aléatoires quelque part sur toute la ligne. Un changement apparemment bénin à une structure provoquant soudainement des paniques qui seraient difficiles à traquer. – RayfenWindspear