it-swarm.com.de

Wie kann ich zwei Strukturen in Golang zusammenführen?

Ich habe zwei json-marshallable anonyme Strukturen.

a := struct {
    Name string `json:"name"`
}{"my name"}

b := struct {
    Description string `json:"description"`
}{"my description"}

Gibt es eine Möglichkeit, sie in json zusammenzuführen, um so etwas zu erhalten:

{
    "name":"my name",
    "description":"my description"
}
6
Dmitry Kapsamun

Sie können beide Strukturen in eine andere einbetten.

type name struct {
    Name string `json:"name"`
}

type description struct {
    Description string `json:"description"`
}

type combined struct {
    name
    description
}

Das JSON-Paket behandelt eingebettete Strukturen wie Unionen, aber dies kann ziemlich schnell klumpig werden.

10
nothingmuch

Es ist ein bisschen verworren, aber ich denke, dass Sie so etwas tun könnten:

    a := struct {
        Name string `json:"name"`
    }{"my name"}

    b := struct {
        Description string `json:"description"`
    }{"my description"}

    var m map[string]string

    ja, _ := json.Marshal(a)
    json.Unmarshal(ja, &m)
    jb, _ := json.Marshal(b)
    json.Unmarshal(jb, &m)

    jm, _ := json.Marshal(m)
    fmt.Println(string(jm))
7
Franck Jeannin

Sie können zwei Strukturen wie folgt zusammenführen:

package main

import (
    "fmt"
    "encoding/json"
)


type b struct {
    Name string  `json:"name"`
    Description string
    Url string
}

type a struct {
    *b
    MimeType string  `json:"mimeType"`
}

func main() {
    bc := b{"test", "testdecription", "testurl"}
    ac := a{nil, "jpg"}

    ac.b = &bc

    js, _ := json.Marshal(ac)

    fmt.Println(string(js) )
}
3

Bei Go dreht sich alles um Zusammensetzung über Vererbung. Leider verwenden Sie anonyme Strukturen, aber da Sie eindeutig versucht haben, sie zu json marschieren, sollten Sie sie besser als Typen definieren:

type name struct {
    Name string `json:"name"`
}
type desc struct {
    Description string `json:"description"`
}

Sie können sie auf dieselbe Weise initialisieren, wie Sie es gerade tun, aber anstelle von struct{<fields>}{init} schreiben Sie einfach

a := name{"foo"}
b := desc{"Description"}

Sie können sie dann beliebig kombinieren, indem Sie schreiben:

c := struct {
    name
    description
}{a, b}

Eine Besonderheit (die Sie vielleicht zuerst stürzen könnte), an die Sie sich beim Zusammenstellen von Typen gewöhnen müssen, ist die Art, wie Sie die Member initialisieren. Angenommen, Sie möchten einen Typ erstellen, der die beiden anderen Strukturen kombiniert:

type foo struct {
    name
    description
}

Sie können es nicht so initialisieren:

o := foo{"Name value", "description value"}

Go beschwert sich über Sie, indem Sie den Typ string als Typ name verwenden. Sie müssen so etwas schreiben:

o := foo{
    name{"Name value"},
    description{Description: "Description val"},//optional with field names
}

Ein Inline-Composite, das aus vorhandenen Objekten (cf c := struct{}{a, b}) besteht, erledigt dies bereits.
Je nachdem, was Sie versuchen, ist es manchmal einfacher, etwas wie das Folgende zu schreiben:

func (s *MyCompositeType) CopyName(n name) {
    s.Name = n.Name
    //copy other fields
}

Es macht das Leben einfacher, wenn Sie zusammengesetzte Typen mehrere Ebenen tief verschachteln.

3