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.