英文:
Flattening nested structs leads to a slice of slices
问题
所以我有一个像这样的结构体:
type Bus struct {
Number string
Name string
DirectStations []Station // Station 是另一个结构体
ReverseStations []Station
}
我试图将这个结构体的实例存储到 Datastore 中:
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"
如何解决这个问题?
编辑:
事实证明,你不能有一个包含其他切片的结构体切片。
英文:
So I have a struct like this
type Bus struct {
Number string
Name string
DirectStations []Station // Station is another struct
ReverseStations []Station
}
and I'm trying to store an instance of this to the Datastore:
key := datastore.NewKey(c, "Bus", bus.Number, 0, nil)
_, err := datastore.Put(c, key, &bus)
but I'm getting the error
datastore:
flattening nested structs leads to a slice of slices:
field "DirectStations"
How does one solve this?
Edit:
Turns out you can't have a slice of struct, where that struct contains other slices.
答案1
得分: 3
只需将此结构编码为 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"` // 这些标签名称必须与 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
英文:
Just encode this struct into json (bytes) and store the json in the datastore
EDIT / UPDATE
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)
}
答案2
得分: 0
对于来到这里的任何人来说,另一个选择是在数据存储中不将结构片段作为子项存储,而是在加载对象时单独加载它们。
类似这样:
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
}
显然,您需要进行错误检查等操作,但这是处理复杂嵌套结构的一种方法。
英文:
Another option for anyone that comes here is to just not store the slice of structures as a child in the datastore then just load them up separately when you're loading the obj
Something like:
type Parent struct {
Id int64 `json:"id"`
Nested []Child `json:"children" datastore:"-"`
...
}
type Child struct {
Id int64 `json:"id"`
ParentId int64 `json:"parent_id"`
...
}
Then when you want to load the parent, let's assume this code is in a service module and you've got a handy data module to actually pull stuff from the datastore (which you probably should)
func LoadParentWithNested(parent_id int64) (Parent, error){
parent := data.GetParent(parent_id)
parent.Nested := data.LoadNested(parent.Id)
return parent
}
Obviously you'll want error checking and all that, but this is kind of what you've got to do for complex nested structures.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论