What different does the * (pointer symbol) makes in the following Go method? - go

I'm following this tutorial: https://github.com/astaxie/build-web-application-with-golang/blob/master/en/02.5.md.
I still don't understand pointers very well so this past confuses me a bit: func (h *Human) SayHi(). I tried removing the * and the output turned out to be exactly the same. Why is the * necessary in this case? Could someone give me an example of a different output with the code below?
package main
import "fmt"
type Human struct {
name string
age int
phone string
}
type Student struct {
Human // anonymous field
school string
}
type Employee struct {
Human
company string
}
// define a method in Human
func (h *Human) SayHi() {
fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}
func main() {
mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}
mark.SayHi()
sam.SayHi()
}

The difference it does make is that the method will be defined on a pointer to a Human struct and all the methods in the struct will subsequently operate on the value pointed to.
If you were to loose the *, the method would operate on a copy of the struct you call the method on, so any write you'd do to the struct in the method would be useless for the code calling the method.
Since the method body only executes a fmt.Printf and prints some values, it does not really make a big difference if the method is defined on the pointer or not.
There are some cases where in the interest of concurrent-safety, you'd better not define methods on pointers, since this may lead to simultaneous access and writing of the underlying struct values.

There are two reasons to use a pointer receiver:
First, to avoid copying the value on each method call, more efficient if the value type is a large struct).
Second, the method can modify the value that its receiver points to.
So in your example, if you add one more dump method to change phone like this:
func (h Human) ChangePhone() {
h.phone = 'whatever'
}
The phone does not change after you call this method, that's why point * comes into play.

Related

Strange behaviour of int inside a struct

Let's say we have this kind of a struct (one of the simplest ever):
type some struct{
I uint32
}
And we want to have a variable of that type and to atomically increment in for loop (possibly in another goroutine but now the story is different). I do the following:
q := some{0}
for i := 0; i < 10; i++ {
atomic.AddUint32(&q.I,1) // increment [1]
fmt.Println(q.I)
}
We're getting what we'd expect, so far so good, but if we declare a function for that type as follows:
func (sm some) Add1(){
atomic.AddUint32(&sm.I,1)
}
and call this function in the above sample (line [1]) the value isn't incremented and we just get zeros. The question is obvious - why?
This has to be something basic but since I am new to go I don't realize it.
The Go Programming Language Specification
Calls
In a function call, the function value and arguments are evaluated in
the usual order. After they are evaluated, the parameters of the call
are passed by value to the function and the called function begins
execution. The return parameters of the function are passed by value
back to the calling function when the function returns.
The receiver sm some is passed by value to the method and the copy is discarded when you return from the method. Use a pointer receiver.
For example,
package main
import (
"fmt"
"sync/atomic"
)
type some struct {
I uint32
}
func (sm *some) Add1() {
atomic.AddUint32(&sm.I, 1)
}
func main() {
var s some
s.Add1()
fmt.Println(s)
}
Output:
{1}
Go Frequently Asked Questions (FAQ)
When are function parameters passed by value?
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.
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 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.
Your function need to receive a pointer for the value to be incremented, that way you are not passing a copy of the struct and on next iteration the I can be incremented.
package main
import (
"sync/atomic"
"fmt"
)
type some struct{
I uint32
}
func main() {
q := &some{0}
for i := 0; i < 10; i++ {
q.Add1()
fmt.Println(q.I)
}
}
func (sm *some) Add1(){
atomic.AddUint32(&sm.I,1)
}

Function declaration syntax: things in parenthesis before function name

I'm sorry I couldn't be more specific in the question title, but I was reading some Go code and I encountered function declarations of this form:
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
...
}
from https://github.com/mattermost/platform/blob/master/api/context.go
func (s *GracefulServer) BlockingClose() bool {
...
}
from https://github.com/braintree/manners/blob/master/server.go
What does the (h handler) and the (s *GracefulServer) between parenthesis mean? What does the entire function declaration mean, taking into account the meaning of the things between parenthesis?
Edit
This is not a duplicate of Whats the difference of functions and methods in Go? : this question came to me because I didn't know what the things in parenthesis before the function name were, not because I wondered what was the difference between functions and methods... if I knew that this declaration was a method I wouldn't have had this question in the first place. If someone has the same doubt as me one day, I don't believe she will go searching for "golang methods" because she doesn't know that this is the case. It would be like wondering what the letter "sigma" means before a mathematical expression (not knowing it means summation) and someone says it's a duplicate of what's the difference between summation and some other thing.
Also, the short answer to this question ("it's a receiver") is no answer to "what's the difference between functions and methods".
This is called the 'receiver'. In the first case (h handler) it is a value type, in the second (s *GracefulServer) it is a pointer. The way this works in Go may vary a bit from some other languages. The receiving type, however, works more or less like a class in most object-oriented programming. It is the thing you call the method from, much like if I put some method A inside some class Person then I would need an instance of type Person in order to call A (assuming it's an instance method and not static!).
One gotcha here is that the receiver gets pushed onto the call stack like other arguments so if the receiver is a value type, like in the case of handler then you will be working on a copy of the thing you called the method from meaning something like h.Name = "Evan" would not persist after you return to the calling scope. For this reason, anything that expects to change the state of the receiver needs to use a pointer or return the modified value (gives more of an immutable type paradigm if you're looking for that).
Here's the relevant section from the spec; https://golang.org/ref/spec#Method_sets
It means ServeHTTP is not a standalone function. The parenthesis before the function name is the Go way of defining the object on which these functions will operate. So, essentially ServeHTTP is a method of type handler and can be invoked using any object, say h, of type handler.
h.ServeHTTP(w, r)
They are also called receivers. There are two ways of defining them. If you want to modify the receiver use a pointer like:
func (s *MyStruct) pointerMethod() { } // method on pointer
If you dont need to modify the receiver you can define the receiver as a value like:
func (s MyStruct) valueMethod() { } // method on value
This example from Go playground demonstrates the concept.
package main
import "fmt"
type Mutatable struct {
a int
b int
}
func (m Mutatable) StayTheSame() {
m.a = 5
m.b = 7
}
func (m *Mutatable) Mutate() {
m.a = 5
m.b = 7
}
func main() {
m := &Mutatable{0, 0}
fmt.Println(m)
m.StayTheSame()
fmt.Println(m)
m.Mutate()
fmt.Println(m)
The output of the above program is :
&{0 0}
&{0 0}
&{5 7}
If you are familiar with c# extension methods,
a go method (a function with a special receiver argument) e.g.
func (v Vertex) Abs() float64
is similar to c# extension method
static float Abs( this Vertex v);
The differences between value types and pointers are described in evanmcdonnal’s answer

Why do my fields get truncated after the function call?

http://play.golang.org/p/xFBSZta2CL
I have been trying everything for 2 hours now. Going into the main function, we immediately get to line 24-26:
prompter.Define(&Field{"name"})
prompter.Define(&Field{"age"})
The define function:
fmt.Printf("fields: %+v\n", c.fields)
c.fields = append(c.fields, f)
fmt.Printf("fields: %+v\n", c.fields)
After the function call, the c.fields array is empty again!!! Output:
fields: []
fields: [0x1040a120]
fields: []
fields: [0x1040a130]
The Go Programming Language
Frequently Asked Questions (FAQ)
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 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.
In Go, all arguments and return values are passed by value. Receivers are passed by value. Use a pointer receiver to change the value. For example,
package main
import (
"fmt"
)
type Prompter interface {
Define(f *Field)
}
type Field struct {
Key string
}
type Provider interface {
Prompt(Prompter)
}
var providers = []Provider{
MyProvider{},
}
type MyProvider struct{}
func (p MyProvider) Prompt(prompter Prompter) {
prompter.Define(&Field{"name"})
prompter.Define(&Field{"age"})
}
type CliPrompter struct {
fields []*Field
}
func NewCliPrompter() *CliPrompter {
return &CliPrompter{
fields: make([]*Field, 0, 100),
}
}
func (c *CliPrompter) Define(f *Field) {
fmt.Printf("fields: %+v\n", c.fields)
c.fields = append(c.fields, f)
fmt.Printf("fields: %+v\n", c.fields)
}
func main() {
providers[0].Prompt(NewCliPrompter())
}
Output:
fields: []
fields: [0x1040a120]
fields: [0x1040a120]
fields: [0x1040a120 0x1040a130]

In golang, how do I re-assign an external reference from within a function?

I'm probably not expressing this correctly in the question, but perhaps this code will make it clearer:
package main
import "fmt"
type Blob struct {
Message string
}
func assign1(bb **Blob) {
*bb = &Blob{"Internally created by assign1"}
}
func (b *Blob) assign2() {
*b = Blob{"Internally created by assign2"}
}
func main() {
x1 := &Blob{"Hello World"}
assign1(&x1)
fmt.Printf("x1 = %+v\n", *x1)
x2 := Blob{"Hello World"}
x2.assign2()
fmt.Printf("x2 = %+v\n", x2)
}
Produces, as desired:
x1 = {Message:Internally created by assign1}
x2 = {Message:Internally created by assign2}
I want to pass a reference (pointer to a pointer) into a function and have the function assign a new value to the pointer such that the calling scope will see that new value.
I've figured out the above two ways of doing this, but I'd like to know if they are actually correct or if there is some hidden flaw. Also, are either of them more idiomatic than the other?
Coming from Java, assign2 just seems wrong but I'm sure I've seen something similar in the encoding/json package. What is that actually doing?
Thanks!
James answers the mechanics of assign2. I'll touch a bit on when to use it.
Let's take a simpler example, first.
type Counter uint
func (c *Counter) Increment() {
*c += 1
}
In the counter example the entire state of the receiver is changing. Similarly for the encoding/json package the entire state of the receiver is changing. That's really the only time I would use that style.
One major advantage of the style: you can define an interface for the change, just like the GobDecoder does.
When I first saw the assign2 style it was a little grating. But then I remembered that (c *Counter) Increment gets translated to Increment(c *Counter) in the machine code and it didn't bother me anymore. I personally prefer assign1-style. (Though, there is no need for the double pointers as orignally posted.)
package main
import "fmt"
type Blob struct {
Message string
}
func assign1(b *Blob) {
*b = Blob{"Internally created by assign1"}
}
func main() {
x1 := Blob{"Hello World"}
assign1(&x1)
fmt.Printf("x1 = %+v\n", *x1)
}
Both forms are valid Go, as you've discovered.
For the assign2 case, the compiler finds that assign2 does not appear in Blob's method set, but it is part of *Blob's method set. It then converts the method call to:
(&x2).assign2()
While it can be confusing if a method then goes and changes x2 like in your example, there are a number of places in the standard library where this pattern is used. Probably the most common one is implementing custom decoding for a type with the encoding/json module: you implement the DecodeJSON method with a pointer receiver, and update the value being pointed to.

Is there any way to bind methods to a Go map other than temporarily assigning them to a variable?

this code works fine but the temp var used to call the function feels clunky
package main
import "fmt"
type Foo struct {
name string
value int
}
// SetName receives a pointer to Foo so it can modify it.
func (f *Foo) SetName(name string) {
f.name = name
}
var users = map[string]Foo{}
func main() {
// Notice the Foo{}. The new(Foo) was just a syntactic sugar for &Foo{}
// and we don't need a pointer to the Foo, so I replaced it.
// Not relevant to the problem, though.
//p := Foo{}
users["a"] = Foo{value: 1}
x := users["a"]
x.SetName("Abc")
users["a"] = x
fmt.Println(users)
}
http://play.golang.org/p/vAXthNBfdP
Unfortunately no. In Go typically pointers are transparent, and values get auto-addressed when you call pointer methods on them. You managed to find one of the few cases where they aren't. That case is map storage -- values in maps are not considered addressable. That is, you can never do val := &map[key].
When you have a value val := Typ{} and methods defined on *Typ, when you try to call val.Method() Go will super secretly do (&val).Method(). Since you can't do &map[key], then this doesn't work so that temporary variable dance you do is the only way.
As for why that's the case, the internals of a map are considered a bit secret to the user, since it's a hashmap it reserves the right to reallocate itself, shuffle around data, etc, allowing you to take the address of any value undermines that. There have been proposals considered to allow this specific case to work (that is: calling a method with a pointer receiver on it), since the fix is so easy, but none have been accepted yet. It may be allowed someday, but not right now.
Following Jsor’s detailed explanation: if you really need to call methods of map values, it seems the only way for now is to use pointers for values.
var users = make(map[string]*Foo)
func main() {
users["a"] = &Foo{value: 1}
users["a"].SetName("Abc")
fmt.Println(users["a"])
}
But that loses you, precisely, the ability to meaningfully print them (values are just memory addresses now). You’d need to write a custom printing function for *Foo:
func (f *Foo) String() string {
return fmt.Sprintf("%v", *f)
}
http://play.golang.org/p/6-y2ewdnre

Resources