goinaction / code

Source Code for Go In Action examples
4.12k stars 2.36k forks source link

Why are we returning a reference in one spot and not in another #31

Open yonatonreid opened 6 years ago

yonatonreid commented 6 years ago

In this file:

https://github.com/goinaction/code/blob/master/chapter2/sample/search/feed.go

We have this code:

var feeds []*Feed
err = json.NewDecoder(file).Decode(&feeds)

// We don't need to check for errors, the caller can do this.
return feeds, err

However in this file:

https://raw.githubusercontent.com/goinaction/code/master/chapter2/sample/matchers/rss.go

// Decode the rss feed document into our struct type.
// We don't need to check for errors, the caller can do this.
var document rssDocument
err = xml.NewDecoder(resp.Body).Decode(&document)
return &document, err

I don't understand why they are handled the way they are handled. Can you explain?

Arirus commented 6 years ago

@yonatonreid In first way, it returns a slice which element is a pointer to Feed . In for statement ,you can get a copy of each element, each size of slice is 24 bytes ; in second way, it returns a pointer , you also can return document, but size of ptr is 8 bytes, much more efficient

ardan-bkennedy commented 6 years ago

The decision to use value or pointer semantics is never based on the data being 8 or 24 bytes in length. Data of those sizes are basically the same once you factor in all the different granularities of how data is moved around. Email me bill@ardanlabs.com if you want to talk about this more.

ardan-bkennedy commented 6 years ago

As a note, it was a mistake to use a slice of pointers to a Feed in this program. By the time I caught it the book was ready to be published :(. The mistake was not because of the size of a Feed value.

earthquakesan commented 3 years ago

@ardan-bkennedy @yonatonreid

I just had exactly the same question in golang general slack and the answer I received is the follows:

Pointers are used to avoid translating nulls (in JSON) to empty strings ("the billion-dollar mistake").

Examples: https://play.golang.org/p/TQ6GGBKK-gA vs. https://play.golang.org/p/ibhTYaKm6Vf