Reputation: 11251
In tutorial is written:
The type
*T
is a pointer to aT
value. The&
operator generates a pointer to its operand.
I am just playing around with pointers in Go and have following:
example := 42
p:=&example
fmt.Println(reflect.TypeOf(&p)) // **int
fmt.Println(reflect.TypeOf(*p)) // int
So if I got it correctly, &p
is a pointer to a pointer to an int value.
What is use of **Type in the Go language?
Upvotes: 6
Views: 4132
Reputation: 46562
A pointer allows you to pass around a memory address, so that multiple scopes can use the same address, and you can change the value at that address without changing the address; effectively allowing you to share memory. A pointer to a pointer allows you to pass around the address to a memory address, so that multiple scopes can use it and you can change the address pointed to by the shared reference. With a normal pointer, if you change the address of the pointer, any other copies of that pointer held elsewhere will become "disconnected" - they will no longer point to the same value.
For example, you might have two variables being operated on in separate workers, and a central reference you want to be able to switch back and forth between them. A pointer to a pointer is one way to achieve this; the central reference can be changed to point to the pointer used by any of the workers. Each worker would hold a pointer to a value which it would operate on normally, without needing to know if the central reference points to its pointer or not.
Or, as @Volker noted, the canonical example of the linked list. Here is an example in C but the pointer logic is the same in Go.
Upvotes: 2
Reputation: 166825
Here's a simple demonstration of the concept of a chain of pointers:
package main
import "fmt"
func main() {
i := 42
fmt.Printf("i: %[1]T %[1]d\n", i)
p := &i
fmt.Printf("p: %[1]T %[1]p\n", p)
j := *p
fmt.Printf("j: %[1]T %[1]d\n", j)
q := &p
fmt.Printf("q: %[1]T %[1]p\n", q)
k := **q
fmt.Printf("k: %[1]T %[1]d\n", k)
}
Playground: https://play.golang.org/p/WL2M1jp1T3
Output:
i: int 42
p: *int 0x10410020
j: int 42
q: **int 0x1040c130
k: int 42
Upvotes: 4
Reputation: 55563
Yes, you got it correctly.
As to "what use", it's the same as everywhere else: you use a pointer in these cases:
A variable has to be changed in some other code — typically another function, — and so you pass a pointer to the memory occupied by that variable to that function so it's able to update that memory via that address.
A value is too large to be passed around fast enough by copying it.
A pointer to a pointer is a bit of a pathological case for Go, but still this can be used in the first case: when you want some function to change the value of a pointer variable your code controls.
Upvotes: 2