go

Go: Value Types vs Reference Types

Posted by Vikash Patel on Sunday, Apr 7, 2024 Reading time: 2 Min

We have two categories of data types (simply, “types”) they are value types and reference types.

Value based types:

Value types are the types that when passed to a function their values is copied and the original copy is not modified.

Here are the value based types in go:

  1. Integer (int8, int16, int32, int64, byte, rune, uint8, uint16, uint32, uint64)
  2. Floating points (float32, float64)
  3. Boolean (bool)
  4. String (string)
  5. Structs (struct)
Example:
// example-val.go
package main

import "fmt"

func main() {
	number := 12

	fmt.Println(number)  // 12
	addOne(number)  // does not change value of `number`
	fmt.Println(number)  // 12

}

func addOne(number int) {
	number = number + 1
}
Output:

$ go run example-val.go

12

12

Example 2 (struct):
// example-val-struct.go
package main

import "fmt"

type person struct {
	name string
	age  int
}

func main() {
	p := person{name: "Person1", age: 30}
	fmt.Printf("%+v\n", p)
	p.updateName("New Person")
	fmt.Printf("%+v\n", p)
}

func (p person) updateName(newName string) {
	p.name = newName
}
Output:

$ go run example-val-struct.go

{name:Person1 age:30}

{name:Person1 age:30}

Reference based types:

Reference types are the types that when passed to a function a reference to the original variable is passed and the new variable in function parameters is actually pointing to the original variable and when it is modified inside the function the original also gets modified. Here are the reference types in go:

  1. slices
  2. arrays
  3. maps
  4. channels
  5. pointers
  6. functions
Example:
// example-ref.go
package main

import "fmt"

func main() {
	mySlice := []string{"Hi", "There", "How", "Are", "You"}
	fmt.Println(mySlice)
	updateSlice(mySlice)  // modifies the original `mySlice`
	fmt.Println(mySlice)
}

func updateSlice(s []string) {
	s[0] = "Bye"
}
Output:

$ go run example-ref.go

[Hi There How Are You]

[Bye There How Are You]

Example 2 (struct pointer):

From previous example in value based types (Example 2 (struct)). We can change the receiver p and make it a pointer-to-person and it will modify the original person when the function `updateName(…)` is called.

// example-ref-struct-pointer.go
package main

import "fmt"

type person struct {
	name string
	age  int
}

func main() {
	p := person{name: "Person1", age: 30}
	fmt.Printf("%+v\n", p)
	p.updateName("New Person")
	fmt.Printf("%+v\n", p)  // updated value
}

func (p *person) updateName(newName string) {
	p.name = newName
}
Output:

$ go run example-ref-struct-pointer.go

{name:Person1 age:30}

{name:New Person age:30}

That’s all.



comments powered by Disqus