Можно ли конвертировать между структурами?

Допустим, у меня есть следующие две структуры

type Struct1 struct {
   name string
   details interface{}
}

type AddressDetails struct {
   street string
}

type StructDetails struct {
   Struct1
   details AddressDetails
}

Я получаю ввод в Struct1 JSON и преобразую его в Struct1 . Теперь можно ли преобразовать это в StructDetails в golang без необходимости StructDetails маршалирования и демаршалирования? Я пытался это, но я получаю ошибку

Всего 2 ответа


Вы можете использовать превосходную библиотеку структуры map[string]interface{} которая преобразует map[string]interface{} в структуру, которую вы хотите. Таким образом, вы можете просто JSON-декодировать ваши данные в интерфейс map [string] {}, а затем декодировать эту карту в нужные вам структуры.

Пример:

package main

import (
    "fmt"
    "encoding/json"
    "github.com/mitchellh/mapstructure"
)

func main() {
    myJson := "{"name": "someName", "age": 20, "job": "teacher"}"
    myMap := make(map[string]interface{})

    err := json.Unmarshal([]byte(myJson), &myMap)

    if err != nil {
        panic(err)
    }

    person := &Person{}
    adult := &Adult{}

    err = mapstructure.Decode(myMap, person)

    if err != nil {
        panic(err)
    }

    fmt.Printf("Person: %#v
", person)

    err = mapstructure.Decode(myMap, adult)

    if err != nil {
        panic(err)
    }

    fmt.Printf("Adult: %#v
", adult)
}

// Structs

type Person struct {
    Name string `mapstructure:"name" json:"name"`
    Age int `mapstructure:"age" json:"age"`
}

type Adult struct {
    Person `mapstructure:",squash"`

    Job string `mapstructure:"job" json:"job"`
}

Посмотрите это в действии на Go Playground .


Вы можете написать функцию для сопоставления Struct1 с StructDetails

func ToStructDetails(s Struct1, d string) *StructDetails {
    return &StructDetails{s, AddressDetails{d}}
}

Помимо составления карт, не существует ли способа заставить пойти сделать преобразование.

Другой способ после демарширования

s := Struct1{"name", "details"}
var sd StructDetails
sd.Struct1 = s
fmt.Println(sd) // {{name details} {}}
sd.details = AddressDetails{"address"}
fmt.Println(sd) // {{name details} {address}}

Есть идеи?

10000