简体   繁体   中英

Initializing a struct with slice data

Golang has the three dot operator (...) which dumps each element of a slice as its own argument when used with a function call, but it seems that a similar mechanic can't be used with a struct initializer.

Is there a way to reduce code clutter by not accessing every element in a slice when initializing a struct?

Is it possible to append a value to a initialized struct one by one or access an index of some sort inside a for loop?

(I suppose it would be possible to access the direct memory location of a initialized struct - but I'd prefer not to do that)

The following doesn't work: (syntax error)

type Stats struct {
    Total uint64

    ICMP uint64

    UDP uint64
    TCP uint64

    FTP  uint64
    HTTP uint64
    MAIL uint64
    P2P  uint64
}

func newStats(slice [][]byte) *Stats {
    var tmp [8]uint64
    var err error

    for i, val := range slice {
        tmp[i], err = strconv.ParseUint(string(val), 10, 32)
        if err != nil {
             // Handle error
        }
    }

    return &Stats{tmp...} // Syntax error
}

Neither does this: (of course)

return &Stats{
    for{ <code> }
}

This works, but I'd hope for a idiomatic, faster way, without syntax copying

return &Stats{
    tmp[0],
    tmp[1],
    tmp[2],
    tmp[3],
    tmp[4],
    tmp[5],
    tmp[6],
    tmp[7],
}

The only way this really can be done is using unsafe and copy as you allude to, but even then you're liable to run into alignment issues. The other "compact" way is to use reflect and a for loop over the fields, but that's going to be slow and not very idiomatic.

The only other possible way is to perhaps introduce your own syntax and write a generator script to be invoked by go generate , which will autoconvert Struct{slice...} into Struct{slice[0], slice[1] ... , slice[n] } where n is the number of fields, but you'll have to roll that on your own.

In addition to Jsor's suggestions, you could create a NewStats method that take an elliptic argument and use it instead of you first example.

Its not idiomatic either, but you would reduce clutter in the code and have to write the ugly part only once...

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