Your post gives a lot of clarity on key concepts. The example where you make use of the nil value of an uninitialized slice within a struct is a really good one. Thanks so much!
On Fri, Feb 3, 2017 at 6:30 PM, Konstantin Khomoutov < flatw...@users.sourceforge.net> wrote: > 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.