GO: passing Arrays & Slices to functions

When passing Arrays as parameters to functions some specialities need to be cared of. Go’s documentation stated, that arrays will be copied.

You would assume, the following function would, according to the steps, work like this: copy the array (when passing), sort the copy and return the median without changing the original array ‚l‘.

see go playground



package main

import (
        "fmt"
        "sort"
       )

func arrayMedian(list []int) (median int) {
   lenAR := len(list)
   if lenAR == 0 {
      return 0
   }
   sort.Ints(list) 
   if lenAR%2 == 0 {
      return (list[lenAR/2-1] + list[lenAR/2]) / 2
   }
   return list[lenAR/2]
}

func main(){
   l := []int{0,3,4,1,0,9,6,3,9,8}
   fmt.Println(l, arrayMedian(l), l)
}

Surprise – if looking at the output, you’ll find the original array ‚l‘ is sorted now.

Why? I guess, passing l by ‚arrayMedian(l)‘ didn’t pass the original array (or generates a copy) but passes a slice over ‚l‘ (rsp: a copy of the slice over ‚l‘), what actually means, that pointers to the ‚l’s list members are passed. The manipulation (here: sorting) is performed on the original array.

What you need to do is this instead:


func arrayMedian(list []int) (median int) {
   lenAR := len(list)
   if lenAR == 0 {
      return 0
   }

   ar := make([]int, lenAR)
   copy(ar, list[:])

   sort.Ints(ar)
   if lenAR%2 == 0 {
      return (ar[lenAR/2-1] + ar[lenAR/2]) / 2
   }

   return ar[lenAR/2]
}

Though you produce a copy manually, sort the copy and return the result by leaving the original array ‚l‘ unchanged.