On Fri, 3 Feb 2017 17:48:18 +0530 Rejoy Nair <rejo...@gmail.com> wrote:
> > > I am trying to pass a slice of data to a struct field . The field > > > has a type of another struct. I get blank values in the output. > > > > > > Here is the code: https://play.golang.org/p/-YZ7UUI--D > > > > > > I 'd like to understand how to pass on the slice data to a struct > > > field. > > > > It's not clear what do you want to achieve as the question mentions > > slices, the code example deals with JSON unmarshaling and unrelated > > value juggling. > > > > But is <https://play.golang.org/p/FxcA0vW9ZU> what you're after? > > (See line 36 there.) > > Thanks!. thats what I was looking for. > > I had tried using the assignment Dt.P = Pr before the unmarshalling > of the JSON to the variable pdata and it would not work. I see. Then, you absolutely positively need to read [1] and then [2] -- in this order. As to your particular case, here's a bunch of related facts to ponder: * json.Unmarshal() is told to unmarshal into a slice value. * The slice it's passed is of length 0, which means that function has to perform several appends to that slice (two, in fact). * Appending to a slice in Go _may update the slice value_ because it might result in relocation of the slice's backing array. * In your case it works because json.Unmarshal() was passed not a slice value itself but a pointer to it (or, to put it differently, an address of the slice value kept in memory somewhere). Because of this, when json.Unmarshal() appends new elements to your slice it merely re-writes that slice's value each time -- via the pointer supplied to it. * When json.Unmarshal() exits, the slice value whose address was passed to that function now represents the "final" state of the slice -- filled with values. We then take it and assign it to a field of your custom struct value. Now the original slice value and that field represent the same slice (and refer to the same underlying array). * If you do this "backwards" -- like you supposedly did by doing something like Pr = make([]Prdata, 0) Dt.P = Pr json.Unmarshal(..., &Pr) you ended up in a situation where json.Unmarshal() changed the value at Pr one or more times when it was appending new elements to that slice, and the slice value ended up being kept in Pr was different from the value kept in the field Dt.P (which supposedly was still nil). * With all these things considered, it's better to rewrite your code to produce [4], or simplify it even further by relying on the fact appending to an uninitialized slice value (nil) allocates the underlying array for that slice as if you called make() for it; this way we can simply initialize only what matters in your custom struct value and let json.Unmarshal() handle slice allocation [5]. TL;DR Doing a := make([]whatever) b := append(a, elem) is allowed to produce b != a, and that's why appending to a slice most of the time is done using a = append(a, elem) In your case this effect was obscured by appending done in a function you did not write but that was due to the fact you weren't familiar with how slices work in Go, so please work through [1, 2]. 1. https://blog.golang.org/slices 2. https://blog.golang.org/go-slices-usage-and-internals 3. https://play.golang.org/p/kaTjPTE2Hx 4. https://play.golang.org/p/Z6B8JUS9ON -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.