【问题标题】:Flattening nested structs leads to a slice of slices展平嵌套结构导致切片
【发布时间】:2014-09-13 12:22:41
【问题描述】:

所以我有一个这样的结构

type Bus struct {
    Number          string
    Name            string
    DirectStations  []Station  // Station is another struct
    ReverseStations []Station
}

我正在尝试将其实例存储到数据存储区:

key := datastore.NewKey(c, "Bus", bus.Number, 0, nil)
_, err := datastore.Put(c, key, &bus)

但我得到了错误

datastore: 
flattening nested structs leads to a slice of slices: 
field "DirectStations"

如何解决这个问题?

编辑:

原来你不能有一个结构切片,该结构包含其他切片。

【问题讨论】:

  • 并非如此。我看过那个帖子,但我真的不明白。
  • “Go 数据存储包不支持两层切片”的部分非常清楚。做什么不太清楚,需要查看应用引擎/数据存储在做什么。
  • 能否请您在此处发布 Station 结构 - 似乎发生错误是因为它也包含切片。
  • @AlexAtNet 看来你是对的。我不能在 Station 结构中有其他切片。

标签: google-app-engine go google-cloud-datastore


【解决方案1】:

只需将此结构编码为 json(字节)并将 json 存储在数据存储中

编辑/更新

package main

import (
    "encoding/json"
    "fmt"
)

type Bus struct {
    Number          string    `json:"number"`
    Name            string    `json:"name"`
    DirectStations  []Station `json:"directstation"` // Station is another struct
    ReverseStations []Station `json:"reversestation"`
}

type Station struct {
    StationName string `json:"stationname"` // these tag names must match exactly  how they look in json
}

func toJson(i interface{}) []byte {
    data, err := json.Marshal(i)
    if err != nil {
        panic(err)
    }

    return data
}
func fromJson(v []byte, vv interface{}) {
    json.Unmarshal(v, vv)

}

func main() {
    bus := Bus{}
    st := []Station{{"station1"}, {"station2"}}
    bus.DirectStations = make([]Station, len(st))
    for i, v := range st {
        bus.DirectStations[i] = v
    }
    bus.Number = "2"
    bus.Name = "BusName"
    js := toJson(bus)
    fmt.Println("JSON OUTPUT", string(js))
    bus2 := Bus{}
    fromJson(js, &bus2)
    fmt.Printf("ORIGINAL STRUCT OUTPUT %#v", bus2)
}

http://play.golang.org/p/neAGgcAIZG

【讨论】:

  • 前段时间我已经放弃了。但是,是的,我似乎记得我已经按照你的建议做了。这一切都适用于在数据存储中写入字节。但是读回字节只是返回一个空序列。在尝试解决这些问题失败后,我放弃了 Go + Google AppEngine。
【解决方案2】:

对于任何来到这里的人来说,另一个选择是不要将结构切片作为子项存储在数据存储中,然后在加载 obj 时单独加载它们

类似:

type Parent struct {
  Id       int64      `json:"id"`
  Nested   []Child    `json:"children" datastore:"-"`  
  ...
}

type Child struct {
  Id       int64      `json:"id"`
  ParentId int64      `json:"parent_id"`
  ...
}

然后,当您要加载父级时,假设此代码位于服务模块中,并且您有一个方便的数据模块来实际从数据存储中提取内容(您可能应该这样做)

func LoadParentWithNested(parent_id int64) (Parent, error){
  parent := data.GetParent(parent_id)
  parent.Nested := data.LoadNested(parent.Id)

  return parent
}

显然,您需要进行错误检查以及所有这些,但对于复杂的嵌套结构,您必须这样做。

【讨论】:

    猜你喜欢
    • 2014-05-24
    • 2014-03-25
    • 2021-05-26
    • 2019-01-21
    • 2019-10-31
    • 1970-01-01
    • 2020-10-04
    • 2013-11-17
    • 2017-02-02
    相关资源
    最近更新 更多