DEV Community

Nerdherd
Nerdherd

Posted on

Golang Pointers

Coming from Ruby, thinking about Golang pointers does require a shift in thinking.

In Ruby,

  • Variables are references to objects.
  • When you assign one variable to another, both variables point to the same object.
  • Changing an object through any variable will be reflected across all references
# Variable array_a is a reference to an Array object
array_a = [1,2,3]

# array_b and array_c now points to the same Array object as array_a
array_b = array_a
array_c = array_a

# Updating array_b will update the underlying Array object defined by 'array_a'
# array_a, array_b and array_c will have the same output
array_b << 4
puts "a: " + array_a
puts "b: " + array_b
puts "c: " + array_c

# output
# a: [1,2,3,4]
# b: [1,2,3,4]
# c: [1,2,3,4]
Enter fullscreen mode Exit fullscreen mode

In Go:

  • Variables can store actual values or pointers (memory addresses) to values.
  • Assigning one variable to another will copy the value
    • This results in two independent variables
  • Pointers allow you reference the same data from multiple variables.-

Go pointers (*Type) references the memory address, where the data is stored.

  • It would like something like *string=0x14000114180.

Go values (Type) holds the actual data

  • Copying will create a new independent instance
// main.go

package main

import "fmt"

func main() {
  // Create an array of length 4, with initial values [1, 2, 3, 0]
  array_a := [4]int{1,2,3}

  // 'array_b' references the same underlying array as 'array_a'
  array_b := array_a
  array_c := array_c

  array_b[3] = 4
  fmt.Println("array_a: " array_a)
  fmt.Println("array_b: " array_b)
  fmt.Println("array_c: " array_c)
}

// output
// array_a:  [1 2 3 0]
// array_b:  [1 2 3 4] <-- only b changed
// array_c:  [1 2 3 0]
Enter fullscreen mode Exit fullscreen mode

To achieve the same result as ruby, we would need to ensure that we are not "copying" the value of array_a to array_b and array_c.

Instead, we would need to assign array_b and array_c a pointer to array_a.

// main.go

package main

import "fmt"

func main() {
  // Create an array of length 4, with initial values [1, 2, 3, 0]
  array_a := [4]int{1,2,3}

  // 'array_b' and 'array_c' is a pointer to the memory address that stores the value of 'array_a'
  array_b := &array_a
  array_c := &array_c

  array_b[3] = 4

  // Since array_a does not store a pointer, we print it directly
  // array_a (value)
  // +-------------------+
  // | [1, 2, 3, 4]      |
  // +-------------------+
  //     ^
  //     |
  // &array_a (address) <--- array_c, array_b (pointers)
  //
  fmt.Println("array_a: ", array_a)
  // '*array_b' is called dereferencing
  // Since 'array_b' stores the pointer to 'array_a', weneed to "dereference it"
  fmt.Println("array_b: ", *array_b)
  fmt.Println("array_c: ", *array_c)
}

// output
// array_a:  [1 2 3 4]
// array_b:  [1 2 3 4] 
// array_c:  [1 2 3 4]
Enter fullscreen mode Exit fullscreen mode

Top comments (0)