Golang: Pointer
What is a Pointer
Go has pointers. A pointer holds the memory address of a variable.
- A pointer is associated with a variable, or some fixed storage, such as slot of a array.
- You can get the pointer of variable. (by
&var_name
) - You can get the value of associated variable. (by
*pointer_name
) - A pointer has a type.
Syntax for Pointer Type
*type
-
The “type syntax” of “pointer of type type”.
e.g.
*int
is the “type syntax” of “pointer of int type”.
package main import "fmt" func main() { // declare a var, named t, of type int var t int // assign value to t t = 3 // declare a var, named tp, of pointer type of t var tp *int // get a pointer to t. Or, think of it as address of t tp = &t // print their type fmt.Printf("%T\n", t) // int fmt.Printf("%T\n", tp) // *int }
Get Pointer of a Variable
&var_name
-
Return a pointer of variable named var_name
The
&
is called Address Operator.
package main import "fmt" func main() { var x = 3 // address of a var fmt.Printf("%v\n", &x) // 0xc420014090 // golang syntax fmt.Printf("%#v\n", &x) // (*int)(0xc420014090) // type of &x fmt.Printf("%T\n", &x) // *int }
Get Pointer's Associate Variable's Value. (Dereferencing Pointer)
*pointer_name
-
Get the value of variable associated with pointer pointer_name.
This is called Dereferencing Pointer or Pointer Indirection.
package main import "fmt" func main() { var x = 3 var xp = &x fmt.Printf("%v\n", xp) // 0xc420014090 var dxp = *xp fmt.Printf("%v\n", dxp) // 3 }
Example: Pointer to Struct
〔see Golang: Struct〕
package main import "fmt" type PP struct { x int y int } func main() { v := PP{1, 2} // get reference of v p := &v // set a field p.x = 999 fmt.Printf("%#v\n", v) // main.PP{x:999, y:2} }
Purpose of Pointer
The purpose of pointer is mostly for speeding up computation.
For example, when you call a function
var x=3; f(x)
golang will make a copy of x, and pass it to f. If you change x in f, it does not change the variable x defined outside of it.
package main import "fmt" func main() { var x = 3 var f = func(x int) int { x = 4 return x } fmt.Printf("%v\n", f(x)) // 4 fmt.Printf("%v\n", x) // 3 }
However, making a copy would slow things down.
So, you have “pointers”. Think of it as address of the variable.
When you pass the address of a variable to a function, the function doesn't make a copy.
However, now if you modify x, the variable outside of f is also modified.
package main import "fmt" func main() { var x = 3 var f = func(x *int) int { *x = 4 return *x } fmt.Printf("%v\n", f(&x)) // 4 fmt.Printf("%v\n", x) // 4 }