go lang

How to use pointers in a go programming language.

In this tutorial you are getting familiar with pointer in go language.

Go is a new language. Although it borrows ideas from existing languages, it has unusual properties that make effective Go programs different in character from programs written in its relatives.

pointer is a variable whose value is the address of another variable, i.e., direct address of the memory location. Basically pointer is a special type of variable which holds the memory address as value. Pointers are useful when we copy large structures or when we want to amend data in a different function.

Why pointers?


To understand pointers need, first, we have to understand the concept of variables. Variables are the labels given to a memory location where the actual data is stored. To access the persisted data we need the memory address of that particular memory location. To remember all the memory addresses manually is an overhead that’s why we use variables to store data and variables can be accessed just by using their label.
Golang also allows saving a hexadecimal number into a variable using the literal expression i.e. number starting from 0x is a hexadecimal number.

Example:

var psal *int = &salary

The *int is a pointer to an integer value. The & is used to get the address (a pointer) to the variable.

fmt.Println(*psal)

The * character is used to dereference a pointer, it returns a value to which the pointer points. The type *P is a pointer to a P value. It’s zero value is nil. The & operator generates a pointer to its operand. The * operator denotes the pointer’s underlying value.

Code Snippet:
package main

import "fmt"

func main() {
	k, l := 24, 8086

	p := &k          // point to k
	fmt.Println(*p) // read k through the pointer
	*p = 29         // set k through the pointer
	fmt.Println(k)  // see the new value of k

	p = &l         // point to l
	*p = *p / 17   // divide l through the pointer
	fmt.Println(l) // see the n ew value of l
}

Output:-

Value of k from pointer =  24
Value of P  0xc000016048
Value of k =  29
Value of l =  475

In the above example, we have created two variables k and l and to p variable which is pointer variable, we are storing k’s memory address.

Update the Pointer:-

As we learned the scope of a variable in that we found we can update/use variable outside the scope but with the help of pointers we can update variable value using pass by reference concept.

Example:

package main

import "fmt"

func change(pv *int) {

    *pv = 21
}

func main() {

    var count int = 44
    fmt.Println(count)

    change(&count)
    fmt.Println(count)
}

Output:

$ go run pointerRef.go 
44
21

From the main() function we passed the reference of count variable to change() function which is changing the value of count variable.

Go pointer used with struct:

This section is answer of how to use go pointer with Struct. Pointers very much frequently used with Struct.

package main

import "fmt"

type Employee struct {
    name       string
    occupation string
}

func change(pu *Employee) {

    pu.name = "Mahesh"
    pu.occupation = "engineer"
}

func main() {

    u := Employee{"Mahesh", "teacher"}
    fmt.Println(u)

    change(&u)

    fmt.Println(u)
}

Output:-

$ go run pointerStruct.go 
{Mahesh teacher}
{Mahesh engineer}

We have a Employee structure. We change the structure inside the change function through a pointer.

Go Pointers with new keyword:-

In go lang, the new keyword takes a type as an argument and allocate memory to fit a value of that type of a variable. If you pass int then allocate memory enough for int data type same for all other data types.

package main

import (
    "fmt"
    "reflect"
)

type Employee struct {
    name       string
    occupation string
}

func main() {

    var pu *Employee = new(Employee)
    fmt.Println(pu)
    fmt.Println(reflect.TypeOf(pu))

    pu.name = "Mahesh Ligade"
    pu.occupation = "teacher"
    fmt.Println(pu)
}

Output:-

$ go run newPointer.go 
&{ }
*main.Employee
&{Mahesh Ligade teacher}
Pointer of Pointer in GO:

Pointer of pointer or double pointers supported by go and we can denote using ** operator.

package main

import "fmt"

func main() {

    var n = 10
    var p = &n // assign address of a to p
    var dp = &p // and then assign address of p to dp

    fmt.Println(n)
    fmt.Println(&n)

    fmt.Println("###################")

    fmt.Println(p)
    fmt.Println(&p)

    fmt.Println("###################")

    fmt.Println(dp)
    fmt.Println(&dp)

    fmt.Println("###################")

    fmt.Println(*dp)
    fmt.Println(**dp) // deference the pointer of pointer value use **
}

Output:-

$ go run doublePointer.go 
10
0xc000016048
###################
0xc000016048
0xc00000e028
###################
0xc00000e028
0xc00000e030
###################
0xc000016048
10
Source Code:
https://github.com/maheshwarLigade/spring-boot-examples
$ git clone https://github.com/maheshwarLigade/GoLanguage-tutorials
$ cd GoLanguage-tutorials
Conclusion:-

Golang pointers are very much similar with pointers in C language. Pointers are very much efficient and powerful in some scenario and we should make sure we use this in those scenario only.