Why are receivers pass by value in Go? - go

Seems like you'd ALWAYS want this:
func (self *Widget) Do() {
}
instead of this
func (self Widget) Do() {
}
If so, then the way to get the former semantics OUGHT to be by using the latter syntax. i.e. receivers ought to be pass by reference.

It is because everything in Go is pass by value. This makes it consistent with other C family languages, and means that you never need to remember whether the situation you're looking at is pass by value or not.
From that link:
As in all languages in the C family, everything in Go is passed by value. That is, a function always gets a copy of the thing being passed, as if there were an assignment statement assigning the value to the parameter. For instance, passing an int value to a function makes a copy of the int, and passing a pointer value makes a copy of the pointer, but not the data it points to. (See the next section for a discussion of how this affects method receivers.)
Then later:
func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct) valueMethod() { } // method on value
For programmers unaccustomed to pointers, the distinction between these two examples can be confusing, but the situation is actually very simple. When defining a method on a type, the receiver (s in the above examples) behaves exactly as if it were an argument to the method. Whether to define the receiver as a value or as a pointer is the same question, then, as whether a function argument should be a value or a pointer. There are several considerations.
First, and most important, does the method need to modify the receiver? If it does, the receiver must be a pointer. (Slices and maps act as references, so their story is a little more subtle, but for instance to change the length of a slice in a method the receiver must still be a pointer.) In the examples above, if pointerMethod modifies the fields of s, the caller will see those changes, but valueMethod is called with a copy of the caller's argument (that's the definition of passing a value), so changes it makes will be invisible to the caller.
By the way, pointer receivers are identical to the situation in Java, although in Java the pointers are hidden under the covers; it's Go's value receivers that are unusual.
Second is the consideration of efficiency. If the receiver is large, a big struct for instance, it will be much cheaper to use a pointer receiver.
Next is consistency. If some of the methods of the type must have pointer receivers, the rest should too, so the method set is consistent regardless of how the type is used. See the section on method sets for details.
For types such as basic types, slices, and small structs, a value receiver is very cheap so unless the semantics of the method requires a pointer, a value receiver is efficient and clear.

Sometimes you don't want to pass by reference though. The semantics of
func (self Widget) Get() Value {
}
Can be useful if for instance you have a small immutable object. The caller can know for certain that this method doesn't modify it's reciever. They can't know this if the reciever is a pointer without reading the code first.
To expand on that for instance
// accessor for things Config
func (self Thing) GetConfig() *Config {
}
Just by looking at this method I can know GetConfig is always going to return the same Config. I can modify that config but I can't modify the pointer to Config inside Thing. It's pretty close to a const pointer inside of Thing.

Seems like you'd ALWAYS want this:
No. The value receiver is more general. It can be used in all the places that a pointer receiver can; but a pointer receiver cannot be used in all the places that a value receiver can -- for example, if you have an rvalue expression of the type Widget; you can call value-receiver methods on it, but not pointer-receiver methods.

Related

Address of Function Receiver Varies Between Methods

I have the following code. https://play.golang.org/p/YAa6cgtA3Vo
The address of the receiver pointer varies between method calls. This is perplexing. Can anyone explain why this is the case? Do I need to pass a pointer to a receiver as an argument in order to maintain the same address?
type myStruct struct {
//struct content is irrelevant
}
func (ptrToStruct *myStruct) returnAddress() **myStruct {
return &ptrToStruct
}
func (ptrToStruct *myStruct) method1() {
addressOfPtr := ptrToStruct.returnAddress()
fmt.Println(&ptrToStruct)
fmt.Println(addressOfPtr)
if &ptrToStruct != addressOfPtr {
fmt.Println("Different addresses!")
}
}
EDIT:
What I want is the address of ptrToStruct and not its value. I know that I could just get it in method1() by typing addressOfPtr = &ptrToStruct but in my use case I have some logic happening in the returnAddress() method and I need it to come from there.
That's simple: when you have var ms myStruct somewhere,
calling ms.returnAddress() would pass the address of the ms variable to returnAddress, and that address would always be the same (this is easily verifyable — try it itself).
Now consider that the ptrToStruct in the returnAddress definition is just a special argument to be passed to that method, and it has a concrete type — *myStruct.
This type internally is just an integer — large enough to store an address of any memory location on your platform/OS combination.
Now consider that when the call ms.returnAddress() is performed, the address of the ms variable is taken and written to the ptrToStruct argument passed to returnAddress. And that argument is also a variable — with the lifetime equal to the duration of the function call, and visible only in that function's body.
This variable is automatically created on the call stack by the code which prepares the function call.
(And the same happens to all the other method arguments.)
So, when you take the address of ptrToStuct, you take the address of a variable appeared at some location on the call stack which will be gone once the method returns.
Now consider that:
goroutine stacks in Go are growable (and hence may be relocated in memory when grown);
a method may be called from different goroutines (each has its own stack);
even if the method is called from the same goroutine multiple times, it may be called from different places in the code path executed by that goroutine.
All of the above may lead to the address of ptrToStruct variable being essentially random from call to call.
What you (probably) actually want is just returning the value of ptrToStruct as is, not its address.
If you feel like not really getting into how ptrToStruct springs into existence and vanishes, consider starting with this.

Does a `_` receiver on a value (non-pointer) still copy the value?

My question is whether or not a copy of a value is made when a method is invoked where _ is the receiver.
type Foo struct {
// Many fields, making a large struct
}
func (_ Foo) Test(v *T) int {
// Here we can't use the receiver but the method is still needed
}
So I'm wondering if Go implementations will still copy the Foo value when Test() is invoked, even though it's impossible to actually mutate the receiver value.
var f Foo
f.Test() // Is this making a copy?
I would also wonder about the case of a pointer, which is automatically dereferenced by default.
var f = new(Foo)
f.Test() // Is this making a copy?
I tried looking at the assembly, and I think it may be making the copy, but I just don't know enough to be sure.
For details on the situation:
This is an odd case where I can't use a pointer. The code is machine generated and required to cause a type to fulfill an interface while doing some initialization on the v parameter. (The generated code has metadata about the Foo that gets set on v.)
So if I make the receiver a pointer, the interface won't be fulfilled for "value" instances. This method will be invoked once for each instance, and instances can sometimes be large and/or created in great numbers, which is why I would like to avoid an unnecessary copy.
According to this blog post, the caller allocates stack elements for return values and the callee populates them.
This leads me to believe that the value is copied and then discarded.
That or a specialized callee would have to be generated in the case of _ receiver

Designing Go packages: when I should define methods on types?

Suppose that I have a type type T intand I want to define a logic to operate on this type.
What abstraction should I use and When ?
Defining a method on that type:
func (T t) someLogic() {
// ...
}
Defining a function:
func somelogic(T t) {
// ...
}
Some situations where you tend to use methods:
Mutating the receiver: Things that modify fields of the objects are often methods. It's less surprising to your users that x.Foo will modify X than that Foo(x) will.
Side effects through the receiver: Things are often methods on a type if they have side effects on/through the object in subtler ways, like writing to a network connection that's part of the struct, or writing via pointers or slices or so on in the struct.
Accessing private fields: In theory, anything within the same package can see unexported fields of an object, but more commonly, just the object's constructor and methods do. Having other things look at unexported fields is sort of like having C++ friends.
Necessary to satisfy an interface: Only methods can be part of interfaces, so you may need to make something a method to just satisfy an interface. For example, Peter Bourgon's Go intro defines type openWeatherMap as an empty struct with a method, rather than a function, just to satisfy the same weatherProvider interface as other implementations that aren't empty structs.
Test stubbing: As a special case of the above, sometimes interfaces help stub out objects for testing, so your stub implementations might have to be methods even if they have no state.
Some where you tend to use functions:
Constructors: func NewFoo(...) (*Foo) is a function, not a method. Go has no notion of a constructor, so that's how it has to be.
Running on interfaces or basic types: You can't add methods on interfaces or basic types (unless you use type to make them a new type). So, strings.Split and reflect.DeepEqual must be functions. Also, io.Copy has to be a function because it can't just define a method on Reader or Writer. Note that these don't declare a new type (e.g., strings.MyString) to get around the inability to do methods on basic types.
Moving functionality out of oversized types or packages: Sometimes a single type (think User or Page in some Web apps) accumulates a lot of functionality, and that hurts readability or organization or even causes structural problems (like if it becomes harder to avoid cyclic imports). Making a non-method out of a method that isn't mutating the receiver, accessing unexported fields, etc. might be a refactoring step towards moving its code "up" to a higher layer of the app or "over" to another type/package, or the standalone function is just the most natural long-term place for it. (Hat tip Steve Francia for including an example of this from hugo in a talk about his Go mistakes.)
Convenience "just use the defaults" functions: If your users might want a quick way to use "default" object values without explicitly creating an object, you can expose functions that do that, often with the same name as an object method. For instance, http.ListenAndServe() is a package-level function that makes a trivial http.Server and calls ListenAndServe on it.
Functions for passing behavior around: Sometimes you don't need to define a type and interface just to pass functionality around and a bare function is sufficient, as in http.HandleFunc() or template.Funcs() or for registering go vet checks and so on. Don't force it.
Functions if object-orientation would be forced: Say your main() or init() are cleaner if they call out to some helpers, or you have private functions that don't look at any object fields and never will. Again, don't feel like you have to force OO (à la type Application struct{...}) if, in your situation, you don't gain anything by it.
When in doubt, if something is part of your exported API and there's a natural choice of what type to attach it to, make it a method. However, don't warp your design (pulling concerns into your type or package that could be separate) just so something can be a method. Writers don't WriteJSON; it'd be hard to implement one if they did. Instead you have JSON functionality added to Writers via a function elsewhere, json.NewEncoder(w io.Writer).
If you're still unsure, first write so that the documentation reads clearly, then so that code reads naturally (o.Verb() or o.Attrib()), then go with what feels right without sweating over it too much, because often you can rearrange it later.
Use the method if you are manipulating internal secrets of your object
(T *t) func someLogic() {
t.mu.Lock()
...
}
Use the function if you are using the public interface of the object
func somelogic(T *t) {
t.DoThis()
t.DoThat()
}
if  you want to change T object, use
func (t *T) someLogic() {
// ...
}
if you donn't change T object and would like a origined-object way , use
func (t T) someLogic() {
// ...
}
but remeber that this will generate a temporay object T to call someLogic
if your like the way c language does, use
func somelogic(t T) {
t.DoThis()
t.DoThat()
}
or
func somelogic(t T) {
t.DoThis()
t.DoThat()
}
one more thing , the type is behide the var in golang.

How do you decide whether your function should use a pointer as is receiver?

Consider a binary tree node:
type Node struct {
value uint8
left, right *Node
}
If I want to add a function to each Node, should it be:
A: func (n *Node) height() int
or
B: func (n Node) height() int
I want to know which of A or B you would choose and why.
I can model linked lists or recursive structs, but I don't know when the receiver should be a pointer or not-a-pointer.
The main difference is the idea of pass by value vs pass by reference
When you're using example A you're passing be reference, meaning that any changes you apply to n inside of func (n *Node) height will apply to the Node you're using to call Node.height().
By comparison, what you're doing in example B is passing by value where you're really just passing a copy of the Node you're using to call Node.height() so any changes to that Node will not apply outside of the function.
Here is a small playground to demonstrate the differences: http://play.golang.org/p/JodPRPBHDg
Notice in the example that when you call node.incHeight(), it goes to the function:
func (n Node) incHeight() uint8 {
n.value++
return n.value
}
Because this is pass by value the node.value is still the same unless you store the returned value as node.value. However, if you call node.incrementHeight() it goes to the function:
func (n *Node) incrementHeight() {
n.value++
return
}
This will change the value of node.value without needing to return anything because its referencing the original struct, rather than a copy of the struct.
So in answer to which would you choose and why, it really depends on whether you want to be able to make lasting changes to the struct you're using to call the function or if you'd rather just pass a copy that can see and alter the values but only while within the function and not have any lasting effects on the original struct.
There is a very nice explanation in https://code.google.com/p/go-wiki/wiki/Style
Receiver Type
Choosing whether to use a value or pointer receiver on
methods can be difficult, especially to new Go programmers. If in
doubt, use a pointer, but there are times when a value receiver makes
sense, usually for reasons of efficiency, such as for small unchanging
structs or values of basic type. Some rules of thumb:
If the receiver is a map, func or chan, don't use a pointer to it.
If the receiver is a slice and the method doesn't reslice or reallocate the slice, don't use a pointer to it.
If the method needs to mutate the receiver, the receiver must be a pointer.
If the receiver is a struct that contains a sync.Mutex or similar synchronizing field, the receiver must be a pointer to avoid copying.
If the receiver is a large struct or array, a pointer receiver is more efficient. How large is large? Assume it's equivalent to passing
all its elements as arguments to the method. If that feels too large,
it's also too large for the receiver.
Can function or methods, either concurrently or when called from this method, be mutating the receiver? A value type creates a copy
of the receiver when the method is invoked, so outside updates will
not be applied to this receiver. If changes must be visible in the
original receiver, the receiver must be a pointer.
If the receiver is a struct, array or slice and any of its elements is a pointer to something that might be mutating, prefer a pointer
receiver, as it will make the intention more clear to the reader.
If the receiver is a small array or struct that is naturally a value type (for instance, something like the time.Time type), with
no mutable fields and no pointers, or is just a simple basic type
such as int or string, a value receiver makes sense. A value
receiver can reduce the amount of garbage that can be generated; if
a value is passed to a value method, an on-stack copy can be used
instead of allocating on the heap. (The compiler tries to be smart
about avoiding this allocation, but it can't always succeed.) Don't
choose a value receiver type for this reason without profiling
first.
Finally, when in doubt, use a pointer receiver.

When should I define methods on values (instead of on pointers) in Go?

Having defined
type MyInt int
I would like to define a method .ShowMe() that just prints the value. I can define this either using *MyInt:
func (this *MyInt) ShowMe() {
fmt.Print(*this, "\n")
}
Or using MyInt:
func (this MyInt) ShowMe() {
fmt.Print(this, "\n")
}
In what cases is it recommended to define methods on values, instead of on pointers?
There are two questions to ask yourself when making this decision:
Do I want to be able to modify the receiver's value?
Will copying the receiver's value be expensive?
If the answer to either of these questions is yes, then define the method on a pointer.
In your example, you don't need to modify the receiver's value and copying the receiver isn't expensive.
For deciding the answer to #2, my rule of thumb is: if the receiver is a struct with more than one field, pass by pointer. Otherwise pass by value.
The Go FAQ (CC-licensed) has an answer:
Should I define methods on values or pointers?
func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct) valueMethod() { } // method on value
For programmers unaccustomed to pointers, the distinction between
these two examples can be confusing, but the situation is actually
very simple. When defining a method on a type, the receiver (s in the
above example) behaves exactly as if it were an argument to the
method. Whether to define the receiver as a value or as a pointer is
the same question, then, as whether a function argument should be a
value or a pointer. There are several considerations.
First, and most important, does the method need to modify the
receiver? If it does, the receiver must be a pointer. (Slices and
maps are reference types, so their story is a little more subtle, but
for instance to change the length of a slice in a method the receiver
must still be a pointer.) In the examples above, if pointerMethod
modifies the fields of s, the caller will see those changes, but
valueMethod is called with a copy of the caller's argument (that's
the definition of passing a value), so changes it makes will be
invisible to the caller.
By the way, pointer receivers are identical to the situation in Java,
although in Java the pointers are hidden under the covers; it's Go's
value receivers that are unusual.
Second is the consideration of efficiency. If the receiver is large, a
big struct for instance, it will be much cheaper to use a pointer
receiver.
Next is consistency. If some of the methods of the type must have
pointer receivers, the rest should too, so the method set is
consistent regardless of how the type is used. See the section on
method sets
for details.
For types such as basic types, slices, and small structs, a value
receiver is very cheap so unless the semantics of the method requires
a pointer, a value receiver is efficient and clear.

Resources