
- Go - Home
- Go - Overview
- Go - Environment Setup
- Go - Program Structure
- Go - Basic Syntax
- Go - Data Types
- Go - Variables
- Go - Constants
- Go - Identifiers
- Go - Keywords
- Go - Operators
- Go - Arithmetic Operators
- Go - Assignment Operators
- Go - Relational Operators
- Go - Logical Operators
- Go - Bitwise Operators
- Go - Miscellaneous Operators
- Go - Operators Precedence
- Go Decision Making
- Go - Decision Making
- Go - If Statement
- Go - If Else Statement
- Go - Nested If Statements
- Go - Switch Statement
- Go - Select Statement
- Go Control Flow Statements
- Go - For Loop
- Go - Nested for Loops
- Go - Break Statement
- Go - Continue Statement
- Go - Goto Statement
- Go Functions
- Go - Functions
- Go - Call by Value
- Go - Call by Reference
- Go - Functions as Values
- Go - Function Closure
- Go - Function Method
- Go - Anonymous function
- Go Strings
- Go - Strings
- Go - String Length
- Go - String Concatenation
- Go - Compare Strings
- Go - Split String
- Go - Substring Extraction
- Go - String Replacement
- Go - String Interpolation
- Go - Parse Date Strings
- Go Arrays
- Go - Arrays
- Go - Multidimensional Arrays
- Go - Multidimensional Arrays
- Go - Passing Arrays to Functions
- Go - Pointers
- Go - Pointers
- Go - Array of pointers
- Go - Pointer to pointer
- Go - Passing pointers to functions
- Go Advanced Control Structures
- Go - Scope Rules
- Go - Dereferencing Pointer
- Go - Structures
- Go - Slice
- Go - Slice of Slices
- Go - Range
- Go - Maps
- Go - Recursion
- Go - Type Casting
- Go - Interfaces
- Go - Type Assertion
- Go - Error Handling
- Go - Concurrency
- Go - Regular Expression
- Go - Inheritance
- Go - Packages
- Go - Templates
- Go - Reflection
- Go - Generics
- Go File Handling
- Go - Read File By Word
- Go - Read File By Line
- Go - Read CSV Files
- Go - Delete File
- Go - Rename & Move File
- Go - Truncate a File
- Go - File Read-Write Mode W/O Truncation
- Go Miscellaneous
- Go - defer Keyword
- Go - Fmt Package
- Go - Zero Value
- Go - Import
Go - Pointers
Pointers in Go are easy and fun to learn. Some Go programming tasks are performed more easily with pointers, and other tasks, such as call by reference, cannot be performed without using pointers. So it becomes necessary to learn pointers to become a perfect Go programmer.
As you know, every variable is a memory location and every memory location has its address defined which can be accessed using ampersand (&) operator, which denotes an address in memory. Consider the following example, which will print the address of the variables defined −
package main import "fmt" func main() { var a int = 10 fmt.Printf("Address of a variable: %x\n", &a ) }
When the above code is compiled and executed, it produces the following result −
Address of a variable: 10328000
So you understood what is memory address and how to access it. Now let us see what pointers are.
What Are Pointers?
A pointer is a variable whose value is the address of another variable, i.e., direct address of the memory location. Like any variable or constant, you must declare a pointer before you can use it to store any variable address. The general form of a pointer variable declaration is −
var var_name *var-type
Here, type is the pointer's base type; it must be a valid C data type and var-name is the name of the pointer variable. The asterisk * you used to declare a pointer is the same asterisk that you use for multiplication. However, in this statement the asterisk is being used to designate a variable as a pointer. Following are the valid pointer declaration −
var ip *int /* pointer to an integer */ var fp *float32 /* pointer to a float */
The actual data type of the value of all pointers, whether integer, float, or otherwise, is the same, a long hexadecimal number that represents a memory address. The only difference between pointers of different data types is the data type of the variable or constant that the pointer points to.
How to Use Pointers?
There are a few important operations, which we frequently perform with pointers: (a) we define pointer variables, (b) assign the address of a variable to a pointer, and (c) access the value at the address stored in the pointer variable.
All these operations are carried out using the unary operator * that returns the value of the variable located at the address specified by its operand. The following example demonstrates how to perform these operations −
package main import "fmt" func main() { var a int = 20 /* actual variable declaration */ var ip *int /* pointer variable declaration */ ip = &a /* store address of a in pointer variable*/ fmt.Printf("Address of a variable: %x\n", &a ) /* address stored in pointer variable */ fmt.Printf("Address stored in ip variable: %x\n", ip ) /* access the value using the pointer */ fmt.Printf("Value of *ip variable: %d\n", *ip ) }
When the above code is compiled and executed, it produces the following result −
Address of var variable: 10328000 Address stored in ip variable: 10328000 Value of *ip variable: 20
Nil Pointers in Go
Go compiler assign a Nil value to a pointer variable in case you do not have exact address to be assigned. This is done at the time of variable declaration. A pointer that is assigned nil is called a nil pointer.
The nil pointer is a constant with a value of zero defined in several standard libraries. Consider the following program −
package main import "fmt" func main() { var ptr *int fmt.Printf("The value of ptr is : %x\n", ptr ) }
When the above code is compiled and executed, it produces the following result −
The value of ptr is 0
On most of the operating systems, programs are not permitted to access memory at address 0 because that memory is reserved by the operating system. However, the memory address 0 has special significance; it signals that the pointer is not intended to point to an accessible memory location. But by convention, if a pointer contains the nil (zero) value, it is assumed to point to nothing.
if(ptr != nil) /* succeeds if p is not nil */ if(ptr == nil) /* succeeds if p is null */
Dereference Pointer in Golang
In Golang, the dereference operator is used to access and manipulate the value stored in the variable pointed to by the pointer. The dereference or indirection operator (*) acts as a unary operator, and it needs a pointer variable as its operand.
The Pointers themselves do not have parameters or return values, but functions that use pointers can have parameters and return values involving pointers.
Syntax
Below is the syntax to dereference a pointer −
*pointer_variable;
Using the above syntax, we can get and update the value of any variable that is being pointed to by the pointer.
How to Dereference a Pointer?
To dereference a pointer, we need to follow the below-given steps:
Step 1: Create a variable and declare a pointer variable.
var x int var ptr *int
Step 2: Initialize the pointer by assigning the address of the variable.
x = 10 ptr = &x
Step 3: Now, we can dereference the pointer to get or update the value of the variable.
*ptr = 20 fmt.Println(x) value := *ptr fmt.Println(value)
Example
In this example, we are demonstrating these three steps to deference a pointer −
package main import "fmt" func main() { x := 10 var ptr *int ptr = &x *ptr = 20 fmt.Printf("Value of x = %d\n", x) value := *ptr fmt.Printf("Value at the address pointed to by ptr = %d\n", value) }
Output
Run the code and check its output −
Value of x = 20 Value at the address pointed to by ptr = 20
What is Dereferencing?
The term "dereferencing" refers to accessing the value that is stored in the memory address referred by the pointer. The dereference operator fetches the value of the target variable.
Example
In this example, we use pointers to store the addresses and values of variables and dereferencing pointers to access their values.
package main import "fmt" func main() { x := 10 p1 := &x y := 10.5 p2 := &y fmt.Printf("Address of 'x': %p, Value of 'x': %d\n", p1, *p1) fmt.Printf("Address of 'y': %p, Value of 'y': %f\n", p2, *p2) }
Output
Run the code and check its output −
Address of 'x': 0xc000110010, Value of 'x': 10 Address of 'y': 0xc000110018, Value of 'y': 10.500000
Manipulating Value by Dereferencing Pointer
The dereference operator allows indirect manipulation of the value of a variable that refers to a pointer.
Example
In this example, we declare an integer variable x and a pointer p that stores the memory address of x. By dereferencing the pointer p, we can access the value of x. So, we can modify the value of x by changing the value stored at the memory address pointed to by p.
package main import "fmt" func main() { var x int = 64 var p *int p = &x fmt.Println("Value of x=", x) fmt.Println("Address of x=", &x) fmt.Println("Value of p=", p) fmt.Println("Dereferenced value of p=", *p) *p = 21 fmt.Println("New value of x=", x) }
Output
Following is the output of the above program
Value of x= 64 Address of x= 0xc000124010 Value of p= 0xc000124010 Dereferenced value of p= 64 New value of x= 21
Dereferencing Structure Pointer
In programming, a struct (short for "structure") is a user-defined data type that allows you to group related data together. It is a composite data type that means it can hold multiple values of different data types.
We can define a struct using the type keyword, followed by the name of the struct and the struct keyword.
In Golang, we use the * operator to dereference a pointer to access the struct's fields, or we can use the shorthand notation with the dot operator (.). Unlike C/C++ ,there is no arrow symbol (->) in Go.
Let's have a clear idea how to access struct fields in Golang −
Using the dereference operator −
(*ptr).Name = "Indu"
Using the shorthand notation −
ptr.Name = "Indu"
Example
In this example, we create a pointer to a 'Student' struct instance and prints the student's name and age using both direct pointer access and dereferencing.
package main import "fmt" type Student struct { name string age int } func main() { p := &Student{"Indu", 18} fmt.Println("Name=", p.name) fmt.Println("Age=", (*p).age) }
Output
Following is the output of the above program
Name= Indu Age= 18
Dereferencing Pointers in Functions
Dereferencing pointers in functions involves accessing and modifying the value stored at the memory address pointing to a pointer.
When you pass a pointer to a function, the function can dereference the pointer to access and manipulate the actual value stored at that memory address. This allows the function to modify the original variable's value.
Declaring a pointer
var FuncPtr func(parameterType) returnType
Referencing a pointer
FuncPtr = functionName
Calling and dereferencing a pointer
x := FuncPtr(parameter)
Example
package main import "fmt" func add(a int, b int) int { return a + b } func main() { var FuncPtr func(int, int) int FuncPtr = add result := FuncPtr(46, 64) fmt.Println("Result=", result) }
Output
Following is the output of the above program
Result= 110
Go Pointers in Detail
Pointers have many but easy concepts and they are very important to Go programming. The following concepts of pointers should be clear to a Go programmer −
Sr.No | Concept & Description |
---|---|
1 |
Go - Array of pointers
You can define arrays to hold a number of pointers. |
2 |
Go - Pointer to pointer
Go allows you to have pointer on a pointer and so on. |
3 |
Passing pointers to functions in Go
Passing an argument by reference or by address both enable the passed argument to be changed in the calling function by the called function. |