Можно ли конвертировать между структурами? - PullRequest
0 голосов
/ 24 марта 2020

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

type Struct1 struct {
   name string
   details interface{}
}

type AddressDetails struct {
   street string
}

type StructDetails struct {
   Struct1
   details AddressDetails
}

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

Ответы [ 2 ]

0 голосов
/ 25 марта 2020

Вы можете использовать превосходную библиотеку mapstructure , которая преобразует map[string]interface{} в желаемую структуру. Таким образом, вы можете просто JSON декодировать свои данные в интерфейс карты [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\n", person)

    err = mapstructure.Decode(myMap, adult)

    if err != nil {
        panic(err)
    }

    fmt.Printf("Adult: %#v\n", 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 Детская площадка .

0 голосов
/ 24 марта 2020

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

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

Помимо сопоставления, нет ли способа заставить go выполнить преобразование.

Другой способ после отмены звонка

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}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...