2 回答
TA贡献1886条经验 获得超2个赞
问题
原因很简单:
var dataGrouped DataGroupedByTS
将 的字段初始化dataGrouped为类型 的所谓零值DataGroupedByTS。
任何复合类型的零值T都由与 的每个字段对应的类型的零值组成T。
因此对于
type DataGroupedByTS struct {
CodeConv string `json:"codeConv"`
Start time.Time `json:"start"`
End time.Time `json:"end"`
Details []struct {
Timestamp time.Time `json:"timestamp"`
Keys []struct {
IDPrm string `json:"idPrm"`
Value float64 `json:"value"`
} `json:"keys"`
} `json:"details"`
}
零值是
type DataGroupedByTS struct {
CodeConv: "",
Start: time.Time(0),
End: time.Time(0),
Details: nil, // watch this!
}
这是因为 的类型Details是[]struct{ ... },即某些结构体的切片,并且任何切片的零值都是nil。
然后,您继续尝试在某个索引处写入不存在的切片(好吧,该切片没有分配任何后备数组来保存其数据)。这会合理地失败,并出现“恐慌:运行时错误:索引超出范围”:未分配的切片有零个元素,因此索引 0 处没有元素,并且没有任何可分配的内容。
修复
两种方式:
预分配目标切片:
var dataGrouped DataGroupedByTS
// ...
dataGrouped.Details = make([]struct{...}, len(apiMain.Details))
for _, detail := range apiMain.Details {
// ...
追加到切片,而不是就地更新其元素:
var dataGrouped DataGroupedByTS
// ...
for _, detail := range apiMain.Details {
dataGrouped.Details = append(dataGrouped.Details, detail)
// ...
append切片就可以了nil。
- 2 回答
- 0 关注
- 183 浏览
添加回答
举报