Why should constructor of Go return address?

As mentioned, yes, the spec allows you to return either values (as non-pointers) or pointers. It’s just a decision you have to make.

When to return pointer?

Usually if the value you return is “more useful” as a pointer. When is it more useful?

For example if it has many methods with pointer receiver. Yes, you could store the return value in a variable and so it will be addressable and you can still call its methods that have pointer receivers. But if a pointer is returned right away, you can “chain” method calls. See this example:

type My int

func (m *My) Str() string { return strconv.Itoa(int(*m)) }

func createMy(i int) My { return My(i) }

Now writing:

fmt.Println(createMy(12).Str())

Will result in error: cannot call pointer method on createMy(12)

But if works if you return a pointer:

func createMy(i int) *My { return (*My)(&i) }

Also if you store the returned value in a data structure which is not addressable (map for example), you cannot call methods on values by indexing a map because values of a map are not addressable.

See this example: My.Str() has pointer receiver. So if you try to do this:

m := map[int]My{0: My(12)}
m[0].Str() // Error!

You can’t because “cannot take the address of m[0]. But the following works:

m := map[int]*My{}
my := My(12)
m[0] = &my // Store a pointer in the map

m[0].Str() // You can call it, no need to take the address of m[0]
           // as it is already a pointer

And another example for pointers being useful is if it is a “big” struct which will be passed around a lot. http.Request is a shining example. It is big, it is usually passed around a lot to other handlers, and it has methods with pointer receiver.

If you return a pointer, that usually suggests that the returned value is better if stored and passed around as a pointer.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)