Home

Published

-

Pass by value & Pass by reference

img of Pass by value & Pass by reference

In Go, everything is passed by value, but it might not always feel that way. Here’s what that means:

Pass by value (simple types):

  • For simple types like int, float, and string, passing by value means a copy of the variable’s value is passed to the function.
  • Any changes made to the variable inside the function do not affect the original variable in the caller.

Code Go example

   package main

import "fmt"

func main() {

	number := 5

	fmt.Println("Value of number in main is", number)
	case1(number)
	fmt.Println("Address of number in main is", &number)
	fmt.Println("After case1, the value of number is", number)
}


func case1(number int){ // here copy of the variable that is 5 is passed
	number = number + 10
	fmt.Println("In case 1, address of number is", number)
	fmt.Println("In case 1, value of number is", &number)
}


// passing the value in arguments always a create a copy of the value of the vairable that is passed
// we can see the two differnt address. simply tells not the same

Example output

   Value of number in main is 5
In case 1, address of number is 15
In case 1, value of number is 0xc000012118
Address of number in main is 0xc000012110
After case1, the value of number is 5

When you pass these types, Go makes a copy of the value. Changes inside the function don’t affect the original variable.

Pass by reference

Code Go example

   package main

import "fmt"

func main() {

	number := 5
	fmt.Println("Value of number in main is", number)
	fmt.Println()
	fmt.Println("Address of number in main is", &number)
	fmt.Println()
	case1(&number)
	fmt.Println("After case2, the value of number is", number)
}


func case1(number *int){ // here copy of the variable that is 5 is passed /// that is why this number holds a different address /// number variable is same but still different because of pointer (different address)
	// number = number + 10  ---> i cannot pointer + 10 ---> dereference it

	fmt.Println("In case 2, value of number is", &number)
	*number = *number + 10

		fmt.Println("In case 2, address of number is", number)
	fmt.Println("In case 2, address of number is", *number)
	fmt.Println("In case 2, value of number is", &number)
}


// passing the value in arguments always a create a copy of the value of the vairable that is passed
// we can see the two differnt address. simply tells not the same

Code output

   Value of number in main is 5

Address of number in main is 0xc000012110

In case 2, value of number is 0xc000052028
In case 2, address of number is 0xc000012110
In case 2, address of number is 15
In case 2, value of number is 0xc000052028
After case2, the value of number is 15
  • Even though everything is technically passed by value.
  • But certain data types like slices, maps, and channels behave as though they are passed by reference
  • Because these types contain internal pointers to underlying data structures.
  • Slices pass a copy of the slice header, but it points to the same underlying array
  • Maps and channels pass a copy of a pointer to the same underlying data
  • Pointers pass a copy of the memory address

This is why changes to slices, maps, and pointers inside functions can affect the original data - you’re working with copies of references that point to the same memory location.

Key points

  • Everything in Go is passed by value. However, the value can itself be a pointer or a reference to data.
  • For simple types (int, float, string), the value is copied, and changes inside functions do not affect the original variable.
  • For slices, maps, channels, and pointers, a copy of the reference is passed, allowing the function to modify the underlying data.