Blog Friends RSS About

Golang: why sort takes value rather than pointer

For golang, every time a variable is passed as parameter, a new copy of the variable is created and passed to called function or method. The copy is allocated at a different memory address.This strategy is called Pass by Value, which has few side effects.

Therefore, when change struct self, we have to pass the pointer to function. For example, I would like to change the age of student:

type student struct {
	name string
	age  int

func changeAge(s *student) {
	s.age = 10

s := student{name: "Ryan Lv", age:  14}

// you need to pass a pointer to this function.

When go through Go by Example, I found a very strange case relating to function invocation.

Counterintuitive example

package main
import "fmt"
import "sort"
func main() {

    strs := []string{"c", "a", "b"}
    sort.Strings(strs) // attention!
    fmt.Println("Strings:", strs)

    ints := []int{7, 2, 4}
    fmt.Println("Ints:   ", ints)

    s := sort.IntsAreSorted(ints)
    fmt.Println("Sorted: ", s)


$ go run sorting.go
Strings: [a b c]
Ints:    [2 4 7]
Sorted:  true

In this example, the counterintuitive fact is sort.Strings(strs) took a slice as parameter, which is a value[1], sorted it, and changed it!

How does it happen?


The key is slice!

A slice is a descriptor of an array segment. It consists of a pointer to the array, the length of the segment, and its capacity (the maximum length of the segment).

When sort.Strings(sliceA), a brand new slice sliceB will be created, which also points to the array.

After the array under the hood has been sorted, I could print the sorted array through SliceA.

That’s the magic! Slice has a pointer to the real array!


  1. At the beginning, I though of slice as “value”. Actually it’s not.


  1. Stack Overflow: Are golang slices pass by value?

  2. Internal of Slice

  3. Stack Overflow: Why does sort take value as parameter, rather than pointer?


27 April 2019