-1

I was recently doing a backtracking question and came across this weird scenario which I am not able to understand. This question is related to listing out all the possible subsets possible from the given array. Here is the code snippet:

func subsets(A []int) [][]int {
    sort.Ints(A)
    res, cur := [][]int{}, []int{}
    if len(A) == 0 {
        return append(res, cur)
    }
    subsetsUtil(A, 0, &res, cur)
    return res
}

func subsetsUtil(A []int, n int, res *[][]int, cur []int) {
    *res = append(*res, append([]int{}, cur...))
    for i := n; i < len(A); i++ {
        cur = append(cur, A[i])
        subsetsUtil(A, i+1, res, cur)
        cur = cur[:len(cur)-1]
    }
}

This code snippet gives me the correct answer but if I remove the pointer to the result slice, i.e.

func subsets(A []int) [][]int {
    sort.Ints(A)
    res, cur := [][]int{}, []int{}
    if len(A) == 0 {
        return append(res, cur)
    }
    subsetsUtil(A, 0, res, cur)
    return res
}

func subsetsUtil(A []int, n int, res [][]int, cur []int) {
    res = append(res, append([]int{}, cur...))
    for i := n; i < len(A); i++ {
        cur = append(cur, A[i])
        subsetsUtil(A, i+1, res, cur)
        cur = cur[:len(cur)-1]
    }
}

Code doesn't work and returns me an empty slice. As far as I understand, slices are passed by reference and not by value, then how is it when I pass the pointer to the result slice, code works and gives me the correct result but for the other case, it is returning me an empty slice? What am I missing?

  • 1
    Note that your code is not using arrays--those are slices. – Jonathan Hall Jul 26 '20 at 15:09
  • 1
    Everything in Go is passed by value, even slices. Note that a slice value is just a view into a (possible shared) backing array. Take the Tour of GO on slices and read the relevant blog posts. – Volker Jul 26 '20 at 15:13

1 Answers1

0

This statement: "As far as I understand, slices are passed by reference and not by value" is not entirely true. Slices are not pure reference types but an aggregate type such as this struct:

type IntSlice struct {
ptr *int
len, cap int
}

So whenever a slice is passed by value a copy will be made of this structure, which is not the same as the one you passed.

piyush
  • 868
  • 13
  • 29
  • Thanks for the clarification. I actually read the go blog post on Arrays, slices (and strings): The mechanics of 'append' but I am still not that clear on why assigning something to 1-D slice works without reference but not for 2-D slice. In both the cases, it will have the pointer to the first element of the array. – Jatin Gupta Jul 26 '20 at 15:50