简体   繁体   中英

Go struct type, fill embedded struct field

I have the following struct type:

type ExportJob struct {
    AssetID    string `json:"asset_id"`
    ObjectType string `json:"object_type"`
    Usage      string `json:"usage"`
    Reference  string `json:"reference"`
    Chunk      string `json:"chunk_id"`
    Ordering   uint64 `json:"ordering"`
    Formats    []struct {
        SizePreset      string `json:"size_preset"`
        Fit             string `json:"fit"`
        OutputFormat    string `json:"output_format"`
        Location        string `json:"location"`
        BackgroundColor string `json:"background_color"`
        Height          uint64 `json:"height"`
        Width           uint64 `json:"width"`
        Trimfactor      uint64 `json:"trimfactor"`
        Quality         uint64 `json:"quality"`
    } `json:"formats"`
}

Now I use this struct in a completely different project, by importing the package, etc. So far so good, but then I want to fill a concrete instance of the struct:

job := workers.ExportJob{
    AssetID:    "blablat",
    ObjectType: "blablab",
    Reference:  "blbla",
    Ordering:   0,
    Chunk:      "blablba,
    Formats:    ?????, // how does this syntax looks like??
}

I first "fill" the root fields, but then I need to fill an array of Formats , but I don't know how this syntax looks like. Can someone point me in the right direction?

https://play.golang.org/p/D17WYx6mRr

To not relay on links only, whole working program:

package main

import (
    "fmt"
)

type ExportJob struct {
    AssetID    string `json:"asset_id"`
    ObjectType string `json:"object_type"`
    Usage      string `json:"usage"`
    Reference  string `json:"reference"`
    Chunk      string `json:"chunk_id"`
    Ordering   uint64 `json:"ordering"`
    Formats    []struct {
        SizePreset      string `json:"size_preset"`
        Fit             string `json:"fit"`
        OutputFormat    string `json:"output_format"`
        Location        string `json:"location"`
        BackgroundColor string `json:"background_color"`
        Height          uint64 `json:"height"`
        Width           uint64 `json:"width"`
        Trimfactor      uint64 `json:"trimfactor"`
        Quality         uint64 `json:"quality"`
    } `json:"formats"`
}

func main() {
    job := ExportJob{
        AssetID:    "blablat",
        ObjectType: "blablab",
        Reference:  "blbla",
        Ordering:   0,
        Chunk:      "blablba",
        Formats: []struct {
            SizePreset      string `json:"size_preset"`
            Fit             string `json:"fit"`
            OutputFormat    string `json:"output_format"`
            Location        string `json:"location"`
            BackgroundColor string `json:"background_color"`
            Height          uint64 `json:"height"`
            Width           uint64 `json:"width"`
            Trimfactor      uint64 `json:"trimfactor"`
            Quality         uint64 `json:"quality"`
        }{struct {
            SizePreset      string `json:"size_preset"`
            Fit             string `json:"fit"`
            OutputFormat    string `json:"output_format"`
            Location        string `json:"location"`
            BackgroundColor string `json:"background_color"`
            Height          uint64 `json:"height"`
            Width           uint64 `json:"width"`
            Trimfactor      uint64 `json:"trimfactor"`
            Quality         uint64 `json:"quality"`
        }{SizePreset: "no",
            Fit:             "blah",
            OutputFormat:    "blub",
            Location:        "loc",
            BackgroundColor: "green",
            Height:          1,
            Width:           2,
            Trimfactor:      4,
            Quality:         7,
        },
        },
    }
    fmt.Println(job)
}

My opinion: ugly as hell and error prone, as it is easy to miss a tag or omit a field and get compiler errors which aren't that helpful. (They tell you, you can't use that as field value or some such, but don't analyse whats the difference between the type you used and the type that was expected, to make it easier for you, to find your omission/typo.)

And I dread to think about, how that looks if you start to pour more than one element in the slice literal.

And yes, you can't omit the tags, as they take part in type identity, as stated here golang spec last paragraph before the last code example.

As grokify pointed out, you don't need to repeat the struct type for each slice element, so this works as well:

package main

import (
    "fmt"
)

type ExportJob struct {
    AssetID    string `json:"asset_id"`
    ObjectType string `json:"object_type"`
    Usage      string `json:"usage"`
    Reference  string `json:"reference"`
    Chunk      string `json:"chunk_id"`
    Ordering   uint64 `json:"ordering"`
    Formats    []struct {
        SizePreset      string `json:"size_preset"`
        Fit             string `json:"fit"`
        OutputFormat    string `json:"output_format"`
        Location        string `json:"location"`
        BackgroundColor string `json:"background_color"`
        Height          uint64 `json:"height"`
        Width           uint64 `json:"width"`
        Trimfactor      uint64 `json:"trimfactor"`
        Quality         uint64 `json:"quality"`
    } `json:"formats"`
}

func main() {
    job := ExportJob{
        AssetID:    "blablat",
        ObjectType: "blablab",
        Reference:  "blbla",
        Ordering:   0,
        Chunk:      "blablba",
        Formats: []struct {
            SizePreset      string `json:"size_preset"`
            Fit             string `json:"fit"`
            OutputFormat    string `json:"output_format"`
            Location        string `json:"location"`
            BackgroundColor string `json:"background_color"`
            Height          uint64 `json:"height"`
            Width           uint64 `json:"width"`
            Trimfactor      uint64 `json:"trimfactor"`
            Quality         uint64 `json:"quality"`
        }{{SizePreset: "no",
            Fit:             "blah",
            OutputFormat:    "blub",
            Location:        "loc",
            BackgroundColor: "green",
            Height:          1,
            Width:           2,
            Trimfactor:      4,
            Quality:         7,
        },
        },
    }
    fmt.Println(job)
}

In my opinion slightly better, but still not good, as you still have more work to do if you alter the embedded type. (In comparsion to naming the embedded type).

Name all of the struct types to avoid duplicating the struct type in composite literals :

type Format struct {
    SizePreset      string `json:"size_preset"`
    Fit             string `json:"fit"`
    OutputFormat    string `json:"output_format"`
    Location        string `json:"location"`
    BackgroundColor string `json:"background_color"`
    Height          uint64 `json:"height"`
    Width           uint64 `json:"width"`
    Trimfactor      uint64 `json:"trimfactor"`
    Quality         uint64 `json:"quality"`
}

type ExportJob struct {
    AssetID    string   `json:"asset_id"`
    ObjectType string   `json:"object_type"`
    Usage      string   `json:"usage"`
    Reference  string   `json:"reference"`
    Chunk      string   `json:"chunk_id"`
    Ordering   uint64   `json:"ordering"`
    Formats    []Format `json:"formats"`
}

Here's an example of a composite literal using these types:

job := ExportJob{
    AssetID:    "blablat",
    ObjectType: "blablab",
    Reference:  "blbla",
    Ordering:   0,
    Chunk:      "blablba",
    Formats: []Format{
        {SizePreset: "no",
            Fit:             "blah",
            OutputFormat:    "blub",
            Location:        "loc",
            BackgroundColor: "green",
            Height:          1,
            Width:           2,
            Trimfactor:      4,
            Quality:         7,
        },
    },
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM