web-dev-qa-db-fra.com

Golang: La conversion entre différents types de structures est-elle possible?

Disons que j'ai deux types similaires définis de cette façon:

type type1 []struct {
    Field1 string
    Field2 int
}
type type2 []struct {
    Field1 string
    Field2 int
}

Existe-t-il un moyen direct d'écrire des valeurs d'un type1 sur un type2, sachant qu'elles ont les mêmes champs? (autre que l'écriture d'une boucle qui copiera tous les champs de la source à la cible)

Merci.

45
Nicolas Marshall

Pour votre exemple spécifique, vous pouvez facilement le convertir playground :

t1 := type1{{"A", 1}, {"B", 2}}
t2 := type2(t1)
fmt.Println(t2)
35
OneOfOne

Pour donner une référence à la réponse de OneOfOne, voir la section Conversions de la spécification.

Il déclare que

Une valeur non constante x peut être convertie en type T dans les cas suivants:

  • x est assignable à T.
  • Le type de x et T ont des types sous-jacents identiques.
  • Le type de x et T sont des types de pointeur non nommés et leurs types de base de pointeur ont des types sous-jacents identiques.
  • Le type de x et T sont des types entiers ou à virgule flottante.
  • Le type de x et T sont des types complexes.
  • x est un entier ou une tranche d'octets ou de runes et T est un type de chaîne.
  • x est une chaîne et T est une tranche d'octets ou de runes.

Le premier cas mis en évidence est votre cas. Les deux types ont le type sous-jacent

[]struct { Field1 string Field2 int }

Un type sous-jacent est défini comme

Si T est l’un des types de valeur booléenne, numérique ou chaîne, ou un littéral de type pré-déclaré, le type sous-jacent correspondant est T lui-même. Sinon, le type sous-jacent de T est le type sous-jacent du type auquel T fait référence dans sa déclaration de type. (spec, Types )

Vous utilisez un type de littéral pour définir votre type, ce dernier est donc votre type sous-jacent.

47
nemo

À partir de Go 1.8, les balises struct sont ignorées lors de la conversion d'une valeur d'un type struct à un autre. Les types type1 et type2 seront convertibles, indépendamment de leurs balises struct, dans cette version de Go. https://beta.golang.org/doc/go1.8#language

13
Ludi Rehak

Nicolas, dans votre dernier commentaire, vous avez dit que vous utilisiez des balises de champ sur la structure; ils font partie de la définition, donc t1 et t2, comme définis ci-dessous, sont différents et vous ne pouvez pas convertir t2 (t1):

type t1 struct {
    Field1 string
}

type t2 struct {
    Field1 string `json:"field_1"`
}

UPDATE : Ce n'est plus vrai à partir de Go 1.8

11
m.kocikowski

Vous pouvez utiliser manuellement une fonction de mappage qui mappe chaque élément de type t1 à t2. Ça va marcher.

func GetT2FromT1(ob1 *t1) *t2 {
     ob2 := &t2 { Field1: t1.Field1, }
     return ob2
}
2
Agniswar Bakshi