Golang: Pointer

By Xah Lee. Date: . Last updated: .

What is a Pointer

Go has pointers. A pointer holds the memory address of a variable.

Syntax for Pointer Type

*type
The “type syntax” of “pointer of type type”. Example: *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 will also be 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

}