Подтвердить что ты не робот

Golang: Возможно ли преобразование между различными типами структур?

Скажем, у меня есть два одинаковых типа:

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

Есть ли прямой способ записи значений из type1 в type2, зная, что они имеют одинаковые поля? (кроме написания цикла, который скопирует все поля из источника в цель)

Спасибо.

4b9b3361

Ответ 1

В вашем конкретном примере вы можете легко преобразовать его playground:

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

Ответ 2

Чтобы дать ссылку на OneOfOne ответ, см. раздел Conversions спецификации.

В нем указано, что

Непостоянное значение x может быть преобразовано в тип T в любом из этих случаи:

  • x присваивается T.
  • x тип и T имеют одинаковые базовые типы.
  • x type и T - это неименованные типы указателей, а их базовые типы указателей имеют одинаковые базовые типы.
  • x type и T являются целыми или с плавающей точкой.
  • x Тип и T являются сложными типами.
  • x - целое число или кусочек байтов или рун, а T - строковый тип.
  • x - строка, а T - фрагмент байтов или рун.

Первый и выделенный случай - ваш случай. Оба типа имеют базовый тип

[]struct { Field1 string Field2 int }

Основной тип определяется как

Если T является одним из предварительно определенных логических, числовых или строковых типов или литерала типа, соответствующий базовый тип сам T. В противном случае T базовый тип является базовым типом типа, к которому T ссылается в объявлении типа. (spec, Types)

Вы используете литерал типа для определения своего типа, чтобы этот тип литерала был вашим базовым типом.

Ответ 3

Николас, в своем последнем комментарии вы сказали, что используете теги полей в структуре; они считаются частью определения, поэтому t1 и t2, как определено ниже, отличаются, и вы не можете разыграть t2 (t1):

type t1 struct {
    Field1 string
}

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

ОБНОВЛЕНИЕ: Это больше не верно с Go 1.8

Ответ 4

Начиная с Go 1.8, теги struct игнорируются при преобразовании значения из одного типа структуры в другой. Типы type1 и type2 будут конвертируемыми, независимо от их структурных тегов, в этом выпуске Go. https://beta.golang.org/doc/go1.8#language

Ответ 5

Вы можете вручную использовать функцию отображения, которая отображает каждый элемент типа t1 на тип t2. Это будет работать.

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

Ответ 6

Вы можете попробовать encoding/json чтобы маршалировать и демаршировать структуры, если они имеют одинаковые поля (с json:"name") и одинаковые базовые типы.

package main

import (
    "encoding/json"
    "fmt"
)

type common struct {
    INT int
}

type A struct {
    XX  []int
    ZZ  []common
    T_T int 'json:"qaq"'
}

type B struct {
    XX  []int
    ZZ  []common
    QAQ int32 'json:"qaq"'
}

func main() {
    a := A{
        XX: []int{1, 2, 3},
        ZZ: []common{
            common{0},
            common{1},
        },
        T_T: 5,
    }

    bs, _ := json.Marshal(a)
    b := new(B)
    json.Unmarshal(bs, b)
    fmt.Printf("a: %+v\n", a)
    fmt.Printf("b: %+v\n", *b)

}
➜  convert go run main.go
a: {XX:[1 2 3] ZZ:[{INT:0} {INT:1}] T_T:5}
b: {XX:[1 2 3] ZZ:[{INT:0} {INT:1}] QAQ:5}