Search code examples
goconstructorpass-by-value

returning value vs pointer in Go constructor


When building a simple object in go, what's the difference between these alternatives?

func NewGender(value string) Gender {
    return Gender{strings.TrimSpace(value)}
}

func NewGender(value string) *Gender {
    return &Gender{strings.TrimSpace(value)}
}

Solution

  • The question is a really broad one, and it depends heavily on the rest of your API. So here are just some things you might need to consider when choosing one over another (in no particular order):

    • Unnecessary pointers lead to more work for the GC. You might win some time by returning a pointer (one word) rather than a struct (zero to many words), but some of that time might later be consumed by the GC scan.

    • Pointers can also signal presence or absence of a thing, although it's generally better to use comma-ok idiom for that, or return an error.

    • Speaking of errors, if you return nil with an error, the chance that the error will be ignored is smaller (because nil pointer dereference will result in panic). Then again, I don't think people who ignore errors are something you should really take into account.

    • If you need some form of tracking (for example, a possibility to inspect all instances ever created by your constructor), you have to return a pointer, so that all changes to the value would be visible to the inspector.

    • If most of the type's methods have a pointer receiver, or most functions in the API accept pointers to the type rather than values, it's more ergonomic to return a pointer.