Pointers

Go has pointers, but Go pointers is less intimidating that those in C/C++.

Basics

Here’s a simple example:

1
2
3
4
var a int = 2
var pa *int = &a
*pa = 3
fmt.Println(a)

Note in C, the pointer is declared as int*, but in Go it’s *int. Also unlike pointers in C, pointers in Go cannot be calculated.

Types of Parameters Passing

With pointers and functions, we need to clarify the types of parameters passed in functions.

There are two types:

  • pass by value
  • pass by reference

In C, we could do either. For Python, most of the time it’s reference passing.

Review in C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

void pass_by_val(int a){
a++;
}

void pass_by_ref(int& a){
a++;
}

int main(){
int a = 3;
pass_by_val(a);
printf("After pass_by_val: %d\n", a);

pass_by_ref(a);
printf("After pass_by_ref: %d\n", a);
}

The outputs will be:

1
2
After pass_by_val: 3
After pass_by_ref: 4

Pass by Value will copy a value to the function; Pass by Reference will link the function to the value’s address by a pointer.
This actually creates confusion and complexity for the language.

Go Pass by Value Only

In Go, there’s only one method: pass by value. However we can simulate pass by reference by using pointers.

Here’s a common example, swap two numbers.

1
2
3
4
5
6
7
8
9
10
func swap(a, b int) {
b, a = a, b
}

func main() {
a, b := 3, 4
fmt.Println(a, b)
swap(a, b)
fmt.Println(a, b)
}

Go supports only pass by value, hence the above won’t swap at all.

1
2
Before Swap: a = 3, b = 4
After Swap: a = 3, b = 4

Now let’s define a new swap that takes two pointer parameters:

1
2
3
4
5
6
7
8
9
10
11
12
func swap_ref(a, b *int) {
*b, *a = *a, *b
}

func main() {
a, b := 3, 4
fmt.Printf("Before Swap: a = %d, b = %d\n", a, b)

ap, bp := &a, &b
swap_ref(ap, bp)
fmt.Printf("After Swap: a = %d, b = %d\n", *ap, *bp)
}

The swap will be successful now:

1
2
Before Swap: a = 3, b = 4
After Swap: a = 4, b = 3

Alternatively we could define the swap function without using pointers:

1
2
3
4
5
6
7
8
9
10
11
func swap_val(a, b int) (int, int) {
return b, a
}

func main(){
a, b := 3, 4
fmt.Printf("Before Swap: a = %d, b = %d\n", a, b)

a, b = swap_val(a, b)
fmt.Printf("After Swap: a = %d, b = %d\n", a, b)
}

The outputs will be

1
2
Before Swap: a = 3, b = 4
After Swap: a = 4, b = 3