doumi1944 2019-07-31 14:25
浏览 54
已采纳

在go中转换数据结构:紧急:运行时错误:索引超出范围

I have a data structure in go:

type APIMain struct {
    CodeConv string    `json:"codeConv"`
    Start    time.Time `json:"start"`
    End      time.Time `json:"end"`
    Details  []struct {
        IDPrm string `json:"idPrm"`
        Keys  []struct {
            Timestamp time.Time `json:"timestamp"`
            Value     float64   `json:"value"`
        } `json:"keys"`
    } `json:"details"`
}

that I need to transform to:

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"`
}

I get:

 panic: runtime error: index out of range

Here is my method but it is failing on the first line of loop:

func groupByTimestamp(apiMain datacheck.APIMain) DataGroupedByTS {
    var dataGrouped DataGroupedByTS
    dataGrouped.CodeConv = apiMain.CodeConv
    dataGrouped.Start = apiMain.Start
    dataGrouped.Start = apiMain.Start
    dataGrouped.End = apiMain.End

    var iDetail = 0
    var iKey = 0
    for _, detail := range apiMain.Details {
        for _, key := range detail.Keys {
            dataGrouped.Details[iDetail].Timestamp = key.Timestamp  // <-- failing here
            dataGrouped.Details[iDetail].Keys[iKey].IDPrm = detail.IDPrm
            dataGrouped.Details[iDetail].Keys[iKey].Value = key.Value
            iKey++
        }
        iDetail++
    }

    return dataGrouped
}

Basically, data originally comes grouped by IDPrm, and I need to group it by timestamp.

How should I do that ? Is there any helpers that could help doing it ?

  • 写回答

2条回答 默认 最新

  • doucheng1063 2019-07-31 16:12
    关注

    The problem

    The reason is simple:

    var dataGrouped DataGroupedByTS
    

    initializes the fields of dataGrouped to the so-called zero value for the type DataGroupedByTS.

    The zero value of any compound type T consists of the zero-values for types corresponding to each of the fields of T.

    So, for

    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"`
    }
    

    the zero value would be

    type DataGroupedByTS struct {
        CodeConv: "",
        Start:    time.Time(0),
        End:      time.Time(0),
        Details:  nil,           // watch this!
    }
    

    That's because the type of Details is []struct{ ... }, that is, a slice of some structs, and the zero-value of any slice is nil.

    You then go on and attempt to write at some index into a non-existing slice (well, the slice without any backing array allocated to hold its data). This reasonably fails with "panic: runtime error: index out of range": an unallocated slice has zero elements, so there is no element at index 0, and there is nothing to assign to.

    The fix

    Two ways:

    1. Preallocate the destination slice:

          var dataGrouped DataGroupedByTS
          // ...
          dataGrouped.Details = make([]struct{...}, len(apiMain.Details))
          for _, detail := range apiMain.Details {
          // ...
      
    2. Append to a slice, rather than updating its elements in place:

          var dataGrouped DataGroupedByTS
          // ...
          for _, detail := range apiMain.Details {
              dataGrouped.Details = append(dataGrouped.Details, detail)
              // ...
      

      It's OK to append to a nil slice.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 宇视监控服务器无法登录
  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥15 DruidDataSource一直closing
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥50 power BI 从Mysql服务器导入数据,但连接进去后显示表无数据