Pointer to a struct (or lack thereof) - pointers

Let's say I have defined this struct:
type Vertex struct {
X, Y float64
}
now it's perfectly legal Go to use it like this:
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := &Vertex{3, 4}
fmt.Println(v.Abs())
}
but it's also ok not to use a pointer:
func main() {
v := Vertex{3, 4}
fmt.Println(v.Abs())
}
The results in both cases is the same, but how are they different, internally? Does the use of pointer makes the program run faster?
PS. I get it that the Abs() function needs a pointer as a receiver. That explains the reason why a pointer has been used later in the main function. But why doesn't the program spit out an error when I don't use a pointer and directly call Abs() on a struct instance?

why doesn't the program spit out an error when I don't use a pointer and directly call Abs() on a struct instance?
Because you can get the pointer to (address of) a struct instance.
As mentioned in "What do the terms pointer receiver and value receiver mean in Golang?"
Go will auto address and auto-dereference pointers (in most cases) so m := MyStruct{}; m.DoOtherStuff() still works since Go automatically does (&m).DoOtherStuff() for you.
As illustrated by "Don't Get Bitten by Pointer vs Non-Pointer Method Receivers in Golang" or "Go 101: Methods on Pointers vs. Values", using a pointer receiver (v *Vertex) is great to avoid copy, since Go passes everything by value.
The spec mentions (Method values):
As with method calls, a reference to a non-interface method with a pointer receiver using an addressable value will automatically take the address of that value: t.Mp is equivalent to (&t).Mp.

Related

Tour of Go, difference between & and no & when referring to a Vector struct

I know using & symbol address the address of the stored value, but as I'm going the "Tour of Go", in the sections where they introducing pointers and special receivers, they have code as follow for referring to a Vector struct to scale and get the absolute value as shown:
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := &Vertex{3, 4}
fmt.Printf("Before scaling: %+v, Abs: %v\n", v, v.Abs())
v.Scale(5)
fmt.Printf("After scaling: %+v, Abs: %v\n", v, v.Abs())
}
With an output of:
Before scaling: &{X:3 Y:4}, Abs: 5
After scaling: &{X:15 Y:20}, Abs: 25
But if I change the main function call to have v := Vector{3.4} instead of v:= &Vector{3.4}, I get the same output. Is it better practice to refer to the memeory address in this case? More of a conceptual circumstance I don't seem to understand.
You will not get the exact same output, notice that the output no longer indicates that you've passed a pointer (the & is missing):
Before scaling: {X:3 Y:4}, Abs: 5
After scaling: {X:15 Y:20}, Abs: 25
The reason you can still call the absolute value method is because Go implicitly takes the address of v for you when it sees that the method exists on a pointer type but you've used the struct directly since it is always possible to take the address of the struct and derive a method call on the pointer receiver.
For more information, see the "Method expressions" section of the Go spec: https://golang.org/ref/spec#Method_expressions
There isn't really enough information in this specific instance to tell you whether it's good or bad practice to use the struct value or always pass a pointer around. This is very dependent on the situation, the size of the struct, whether you want your value stack or heap allocated, and any number of other factors. However, for most programs it probably won't make a difference and I'd advise that it's not worth worrying about early on as you learn Go.

How to print dereferenced value of field without explicitly specifying that field golang

package main
import (
"fmt"
)
type outer struct {
in *int
}
func main() {
i := 4
o := outer{&i}
fmt.Printf("%+v", o)
}
I'd like to see {in:4} at the end of this, not {in:0x......}, i.e. pretty print the data structure.
I'd like to accomplish this in a similar manner to the code posted (e.g. with a fmt shortcut similar to %+v or an analogous solution).
This is for autogenerated code from a required field of a thrift struct.
What's the best way to go about this?
When you use &i it does not dereference i. Rather it references i, which means that it copies the address of i into o. See the documentation for the Address operators.
From what I gather, you should be able to use *o to dereference the pointer; in other words, go from the address back to the original variable.
For an operand x of pointer type *T, the pointer indirection *x denotes the variable of type T pointed to by x. If x is nil, an attempt to evaluate *x will cause a run-time panic.

What use case does pointers to pointer (eg **int) have?

This is pointers to pointers
package main
import "fmt"
func main() {
var num int
fmt.Println(&num) // 0x...0
makePointer(&num)
}
func makePointer(firstPointer *int) {
fmt.Println(firstPointer) // 0x...0
fmt.Println(&firstPointer) // 0x...1
makePointerToAPointer(&firstPointer)
}
func makePointerToAPointer(secondPointer **int) {
fmt.Println(secondPointer) // 0x...1
fmt.Println(&secondPointer) // 0x...2
}
When would you actually use this? You can properly come up with something where it would be easier to do something else, but that is not what I asking about. I really want to know where in production you would use this?
Pointers to pointers make sense in function parameters sometimes; not **int probably, but a pointer to a pointer to some struct, where you want the function to be able to change what object a variable points to, not just to change the contents of the struct. For example, there are a few functions in the internals of the Go compiler that take a **Node (see cmd/compile/internal/gc/racewalk.go).
I've also written a couple of functions myself that take a **html.Node; they operate on an HTML page that may or may not have already been parsed into a tree of *html.Nodes, and they may or may not need to parse the page—but if they do, I want to keep the parsed tree around so that I don't have to parse it again. These are in github.com/andybalholm/redwood/prune.go.
They are much more common in languages that do not have multiple return values, since they can be used as a way to return an additional value that is a pointer. Many Objective-C methods take an NSError** as their last parameter so that they can optionally return an NSError*.
The goal to pass a pointer to something is if there is need to modify the pointed value. (We also use pointers to avoid copying large data structures when passing, but that is just for optimization.)
Like in this example:
func main() {
var i int
fmt.Println(i)
inc(&i)
fmt.Println(i)
}
func inc(i *int) {
*i++
}
Output is the expected (try it on the Go Playground):
0
1
If parameter of inc() would receive an int only, it could only modify the copy and not the original value, and so the caller would not observe the changed value.
Same goes with pointer to pointer to something. We use pointer to pointer to something, if we need to modify the pointed value, that is the pointed pointer. Like in this example:
func main() {
var i *int
fmt.Println(i)
alloc(&i, 1)
fmt.Println(i, *i)
setToNil(&i)
fmt.Println(i)
}
func alloc(i **int, initial int) {
*i = new(int)
**i = initial
}
func setToNil(i **int) {
*i = nil
}
Output (try it on the Go Playground):
<nil>
0x1040a130 1
<nil>
The reason why pointer to pointer is not really used is because modifying a pointed value can be substituted by returning the value, and assigning it at the caller:
func main() {
var i *int
fmt.Println(i)
i = alloc(1)
fmt.Println(i, *i)
i = setToNil()
fmt.Println(i)
}
func alloc(initial int) *int {
i := new(int)
*i = initial
return i
}
func setToNil() *int {
return nil // Nothing to do here, assignment happens at the caller!
}
Output is the same (address might be different) (try it on the Go Playground):
<nil>
0x1040a130 1
<nil>
This variant is easier to read and maintain, so this is clearly the favored and wide-spread alternative to functions having to modify a pointer value.
In languages where functions and methods can only have 1 return value, it usually requires additional "work" if the function also wants to return other values besides the pointer, e.g. a wrapper is to be created to accommodate the multiple return values. But since Go supports multiple return values, need for pointer to pointer basically drops to zero as it can be substituted with returning the pointer that would be set to the pointed pointer; and it does not require additional work and does not make code less readable.
This is a very similar case to the builtin append() function: it appends values to a slice. And since the slice value changes (its length increases, also the pointer in it may also change if a new backing array needs to be allocated), append() returns the new slice value which you need to assign (if you want to keep the new slice).
See this related question where a pointer to pointer is proposed (but also returning a pointer is also viable / preferred): Golang: Can the pointer in a struct pointer method be reassigned to another instance?
In the same way a pointer to a value lets you have many references to the same value for a consistent view of the value when it changes, a pointer to a pointer lets you have many references to the same reference for a consistent view of the pointer when it changes to point to a different location in memory.
I can't say I've ever seen it used in practice in Go that I can think of.

Cast a struct pointer to interface pointer in Golang

I have a function
func doStuff(inout *interface{}) {
...
}
the purpose of this function is to be able to treat a pointer of any type as input.
But when I want to call it with a the pointer of a struct I have an error.
type MyStruct struct {
f1 int
}
When calling doStuff
ms := MyStruct{1}
doStuff(&ms)
I have
test.go:38: cannot use &ms (type *MyStruct) as type **interface {} in argument to doStuff
How can I cast &ms to be compatible with *interface{}?
There is no such thing as a "pointer to an interface" (technically, you can use one, but generally you don't need it).
As seen in "what is the meaning of interface{} in golang?", interface is a container with two words of data:
one word is used to point to a method table for the value’s underlying type,
and the other word is used to point to the actual data being held by that value.
So remove the pointer, and doStuff will work just fine: the interface data will be &ms, your pointer:
func doStuff(inout interface{}) {
...
}
See this example:
ms := MyStruct{1}
doStuff(&ms)
fmt.Printf("Hello, playground: %v\n", ms)
Output:
Hello, playground: {1}
As newacct mentions in the comments:
Passing the pointer to the interface directly works because if MyStruct conforms to a protocol, then *MyStruct also conforms to the protocol (since a type's method set is included in its pointer type's method set).
In this case, the interface is the empty interface, so it accepts all types anyway, but still.

What pointers may be used for in Go?

I think I understand what pointer is but I don't quite understand when to use it.
The below snippet is from "A Tour of Go".
What is the purpose of "*Vertex" and "&Vertex"?
I replaced them with "Vertex" and it run fine.
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := &Vertex{3, 4}
fmt.Println(v.Abs())
}
That's not a particularly good example of the pointer/value distinction, because in that case they're interchangeable! Pointers are useful when you need to mutate data "remotely" (from another function).
func (v Vertex) SetX(x int) {
v.X = x
}
func main() {
v := Vertex{3, 4}
fmt.Println(v)
v.SetX(1)
fmt.Println(v)
}
As you'll note, this doesn't change anything (strictly speaking, it changes a copy of the vertex, but that's just semantics in most cases)! The value of v is still {3,4}. Trying instead with:
func (v *Vertex) SetX(x int) {
v.X = x
}
func main() {
v := &Vertex{3, 4}
fmt.Println(v)
v.SetX(1)
fmt.Println(v)
}
And suddenly, it works, the second time it prints {1,4}. Now, if you're curious, you may decide to experiment and change v := &Vertex{3, 4} to v := Vertex{3, 4}. Indeed, the above snippet still works. Strange. Likewise, if you change the same line in the second snippet to contain a pointer, it also works the same way.
Why? Go has "transparent" pointers. In other languages with explicit pointer values like C or C++, you have to explicitly use the operators & and * to dereference a pointer. C and C++ even have special syntax for pointer chasing on field access and method calls v->SetX.
For better or worse, Go hides this from you. If you have a value and need to call a pointer method, Go will happily do (&v).Method() for you, if you need to dereference to call a value method, it happily does (*v).Method() automatically. This is true in most cases, there are a few corner cases with things like maps where this doesn't apply, but in general this holds.
So, when it comes down to it, when should you use a pointer receiver on a method? The answer, really, is "most of the time." The Go Style Guide generally recommends using pointer type method receivers except when the receiver is a direct alias for a map, func, or chan, it's a slice that doesn't need reslicing, or you're doing optimizations on small, immutable data types (because pointer chasing is a little bit slower than copying). I'd add to that that you generally shouldn't use direct pointers to pointers.
Generally, when you have no idea which to use, use a pointer receiver. 99% of the time using a pointer will give you the behavior you expect, especially if you're used to languages like Python or C#. It's comparatively rare that incorrectly using a pointer causes a bug, compared the probability of getting a bug because your Setter method isn't actually setting anything.
This particular example is bad because the method defined on pointer type, *Vertex, does not attempt to mutate the value of its receiver (the value the method is called on).
In Go, everything is ever passed/assigned by value — including pointers. So, when you have a method
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
(notice there's no * in front of Vertex in the receiver's type specification), it works just OK because when you do
v := Vertex{2, 3}
x := v.Abs()
the value of v at the v.Abs() call site is copied to the value the Abs() method receives.
Now suppose you want to change (mutate) some of the Vertex's variables using a method call. A naive approach, like in,
func (v Vertex) SetX(x float64) {
v.X = x
}
v := Vertex{2, 3}
v.SetX(-5)
// Here, v.X is still 2
won't work because it will change X of the value v which has been copied to the callee when the call was made; the method changed the X of the copy—a change only seen in the method's scope.
On the other hand, if you were to define that method on the pointer (which holds the address of an actual variable holding a value instead of the value itself), that would work:
func (v *Vertex) SetX(x float64) {
v.X = x
}
v := Vertex{2, 3}
v.SetX(-5)
Here, the compiler would take the address of v at the point SetX() is called and pass it to the method. The method would then use that address to refer to the value in the caller's scope.
The syntactic confusion is because Go (in most cases) allows you to not use operators to take address of a value and dereference that address.
If you're coming from one of popular languages like PHP, Python etc the chief difference is that in many of them objects are "special" and are always passed by reference. Go is more low-level and tries not to use magic behind programmer's back, so you have to be explicit about whether you want to pass a pointer or a copy of the value to a method.
Note that this is not only about whether a method is able or is not able to mutate its receiver; performance things might also play a role here.

Resources