简体   繁体   中英

Flattening nested structs leads to a slice of slices

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.

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)
}

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

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.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM