Golang: pointers – detailed overview
Tags: programming, go, beginners
Published: 2019-04-20 14:46:45

---
title: Golang: pointers – detailed overview
published: true
tags: programming,golang,beginners
canonical_url: https://rtfm.co.ua/en/golang-ukazateli-podrobnyj-razbor-2/
---

![](https://rtfm.co.ua/wp-content/uploads/2018/04/golang-color-icon2.png) What is the _pointer_?

Shortly, the pointer is a variable which stores an address of another variable, where some data is stored.

### A pointer example

Let’s take the simplest example where a pointer is used:

```
package main

import "fmt"

func main() {
    a := 1
    b := &a
    fmt.Println("A: ", a)
    fmt.Println("B: ", b)
    fmt.Println("B: ", *b)
}
```

Here:

1. a variable `a` is created with the integer type and value _1_
2. a variable `b` is created with the _pointer to the integer_ type (see below)
3. and data output:
  1. first just the `a` value
  2. the _value_(!) or _content_ of the `b` variable
  3. finally, we are getting the value of the `a`, to which the `b` is pointed to (will look at the `*` and `&` operators bit later)

Run the code:

```
$ go run pointers_example.go
A:  1
B:  0xc0000140e8
B:  1
```

On the second line, we are seeing the memory address, where the `b` pointer is pointed.

On the third line – we got value from this memory address.

The pointer could be initialized in a more amply way with types specification instead of using `:=` so the code will look like:

```
...
func main() {
    var a int = 1
    var b *int = &a
    fmt.Println("A: ", a)
    fmt.Println("B: ", b)
    fmt.Println("B: ", *b)
}
...
```

In the `var b *int = &a` line we set that the `b` variable is a pointer to the integer data.

In the same way, a pointer to the string data could be created just with the `*string` instead of the `*int` in its data type:

```
...
    var c *string  
    fmt.Printf("The C var type: %T, default value: %v\n", c, c)
    var d string = "This is a string"
    c = &d
    fmt.Printf("The C var type: %T, default value: %v, string value: %s\n", c, c, *c) 
...
```

here:

1. the `c` variable is created as a pointer to the string data
2. using `Printf()`‘s modifiers the `c` variable’s data type (`%T`) and its value (`%v`) are displayed
3. the `d` variable is created with the string data type and “_This is a string_” value
4. for the `c` variable the memory address of the `d` variable is set
5. using `Printf()`‘s modifiers the `c` variable’s data type (`%T`), its value (`%v`), and the value from the memory address which is stored in the `c`

Run:

```
$ go run pointers_example.go
The C var type: *string, default value: <nil>
The C var type: *string, default value: 0xc0000101e0, string value: This is a string
```

### `*` and `& operators`

We already used them in examples above but let’s take a closer look.

The `*` operator is a _dereference operator_.

The _dereference_ here means that we are getting a value not of a pointer (which stores an address) but from the memory address where this pointer is… Well – pointed to :-)

Let go back to our previous example:

```
...
fmt.Printf("The C var type: %T, default value: %v, string value: %s\n", c, c, *c)
...
```

Here:

- `default value: %v` with the `с` – displays a value which is stored in the  c variable – a memory address, where c is pointed to
- `string value: %s` with the `*с` – displays a value which is got after calling the memory from the `c` variable

The `&` operator returns a variable’s memory address.

For example, let’s add to our previous example one more line and let's display addresses using `Printf()` with `%p` modifier:

```
...
    var c *string  
    fmt.Printf("The C var type: %T, default value: %v\n", c, c)
    var d string = "This is a string"
    c = &d
    fmt.Printf("The C var type: %T, default value: %v, string value: %s\n", c, c, *c)
    fmt.Printf("The D adress: %p\nThe C address: %p\nThe C value: %v\n", &d, &c, c)
...
```

Check:

```
$ go run pointers_example.go
The C var type: *string, default value: <nil>
The C var type: *string, default value: 0xc0000101e0, string value: This is a string
The D adress: 0xc0000101e0
The C address: 0xc00000e028
The C value: 0xc0000101e0
```

Here we got _0xc0000101e0_ value as the `d` variable address, _0xc00000e028_ as the address of the `c` variable, but the `c` itself stores address of the `d` variable – _0xc0000101e0_.

Actually, a data initialization in the `c` pointer variable is done by getting the address of the `d` variable:

```
...
c = &d
...
```

### The `new()` function

To define and initialize a pointer using the `var pointername *type` notation – you can use the built-in [`new()`](https://golang.org/pkg/builtin/#new) Go function which accepts a data type as the first argument and will return a pointer to a memory allocated for a variable’s data:

```
...
    a := 1
    b := new(int)
    fmt.Printf("A: %d, B: %v, %v\n", a, b, *b)
    b = &a
    fmt.Printf("A: %d, B: %v, %v\n", a, b, *b) 
...
```

Here:

1. the `a` variable is created with value _1_
2. the `b` variable is created which will hold a pointer to the memory returned by the new() function and which keeps 0 for now, as already allocated memory can’t hold `nil`
3. the `b`‘s value is updated with the `a`‘s address

Check:

```
$ go run pointers_example.go
A: 1, B: 0xc000014100, 0
A: 1, B: 0xc0000140e8, 1
```

### Changing a pointer’s value

Well, this is not correct to say “changing a pointer’s value” as a pointer variable stores a memory address – not a value itself.

But using a pointer we can change this value in a memory location to which this pointer is pointed to.

For example:

```
...
    a := 1
    b := &a
    fmt.Println("A: ", a)
    fmt.Println("B: ", *b)
    *b = 2
    fmt.Println("B: ", *b)
...
```

Here:

1. the `a` variable has value _1_
2. the `b` variable has the `a`‘s address
3. the `a` variable value displayed
4. the value displayed take from the address where the `b` is pointed to
5. we are changing the value in this memory to the _2_
6. and displays the new value

Run the code:

```
$ go run pointers_example.go
A:  1
B:  1
B:  2
```

### Passing a pointer as a function’s argument

You can pass a pointer to a function as its argument.

For example:

```
package main
import "fmt"
func setVal(b *int) {
    *b = 2
}
func main() {
    a := 1
    b := &a
    fmt.Println("Init values")
    fmt.Println("A: ", a)
    fmt.Println("B: ", *b)
    setVal(b)
    fmt.Println("Changed values")
    fmt.Println("A: ", a)
    fmt.Println("B: ", *b)
}
```

Here we are creating a `setVal()` function which accepts an integer pointer as an argument and will change a value in the address passed with this pointer.

Check it:

```
$ go run pointers_example.go
Init values
A:  1
B:  1
Changed values
A:  2
B:  2
```

After calling the `setVal()` –  the`a` and `b` will display a new value.

Even more – we could pass just an address of the `a`‘s variable to the `setVal()`:

```
...
func setVal(b *int) {
    *b = 2
}
func main() {
    a := 1
    fmt.Println("Init values")
    fmt.Println("A: ", a)
    setVal(&a)
    fmt.Println("Changed values")
    fmt.Println("A: ", a)
}
```

The result is:

```
$ go run pointers_example.go
Init values
A:  1
Changed values
A:  2
```

### Functions: passing arguments by value and by reference

A bit offtopic here but using the example above the difference between passing _argument by value_ and _argument by reference_ also can be displayed.

Let’s update this example:

```
...
func setVal(b *int, c int) {
    *b = 2
    c = 4
    fmt.Printf("B from setVal(). Poiner to: %p, val: %v\n", b, *b)
    fmt.Printf("C from setVal(). Addr: %p, val: %v\n", &c, c)
}
func main() {
    a := 1
    b := &a
    c := 3
    fmt.Println("Init values")
    fmt.Printf("A from main(). Addr: %p, val: %v\n", &a, a)
    fmt.Printf("B from main(). Poiner to: %p, val: %v\n", b, *b)
    fmt.Printf("C from main(). Addr: %p, val: %v\n", &c, c)
    fmt.Println("Changed values")
    setVal(b, c)
    
    fmt.Printf("A from main(). Addr: %p, val: %v\n", &a, a)
    fmt.Printf("B from main(). Poiner to: %p, val: %v\n", b, *b)
    fmt.Printf("C from main(). Addr: %p, val: %v\n", &c, c)
}
```

Here:

1. get the `a` variable address and its value
2. get the address which is stored in the `b` variable and then the data which is stored on this address
3. get the `c` variable address and its value
4. call the `setVal()` function and pass the `a`‘s value by the reference in the `b` and the `c` – as a value
5. in the `setVal()` getting the address which is stored in the `b` variable and the value which is stored there
6. in the `setVal()` getting the `c` variable address and the value which is stored in this memory area
7. in the `main()` getting the `a`‘s address and the value stored there
8. in the `main()` getting the address which is stored in the `b` variable and value from there
9. in the `main()` getting the `c` variable address and the value which is stored there

Run it:

```
$ go run pointers_example.go
Init values
A from main(). Addr: 0xc0000140e8, val: 1
B from main(). Poiner to: 0xc0000140e8, val: 1
C from main(). Addr: 0xc000014100, val: 3
Changed values
B from setVal(). Poiner to: 0xc0000140e8, val: 2
C from setVal(). Addr: 0xc000014130, val: 4
A from main(). Addr: 0xc0000140e8, val: 2
B from main(). Poiner to: 0xc0000140e8, val: 2
C from main(). Addr: 0xc000014100, val: 3
```

Here:

1. the `a` is stored in the _0xc0000140e8_ location and has value _1_
2.  the`b` is pointed to the same location _0xc0000140e8_ and returns the same _1_ value
3. the`c` is stored in the _0xc000014100_ location with the _3_ value
4. the `setVal()` is called
5. the`b` in the `setVal()` still pointed to the _0xc0000140e8_ location with the _2_ as its value
6. the `c` in the `setVal()` got its new address _0xc000014130_ where the _4_ is stored
7. the`a` in the `main()` now keeps the _2_ value from the same _0xc0000140e8_ location
8. `the b` in the `main()` still the same as it is in the `setVal()` – points to the same location and returns the same value
9. in the `main()` for the `c` variable nothing was changed as the `c` in the `setVal()` has own address _0xc000014130_, but the `c` in the `main()` uses the _0xc000014100_ location

Actually, that’s all need to know to better understand what pointers are and how to use them.

### Similar posts

- <small>04/13/2019</small> [Go: checking public repositories list in Github. Go slices comparison. The first Golang experience.](https://dev.to/setevoy/go-checking-public-repositories-list-in-github-go-slices-comparison-the-first-golang-experience-1ddm)<small> (0)</small>  
- <small>04/08/2019</small> [Atom: useful plugins](https://rtfm.co.ua/en/atom-useful-plugins/)<small> (0)</small>  
- <small>04/01/2019</small> [Redis: replication, part 3 – redis-py and work with Redis Sentinel from Python](https://dev.to/setevoy/redis-replication-part-3-redis-py-and-work-with-redis-sentinel-from-python-mb9)<small> (0)</small>