0

My purpose is to remove one element from specific slice, and the code is something like:

func main() {
    s := []int{0, 1, 2, 3, 4}
    remove(s, 3)
    fmt.Println(s, len(s), cap(s))
}

func remove(s []int, idx int) {
    if idx < 0 || idx >= len(s) {
        return
    }
    copy(s[idx:], s[idx+1:])
    s = s[:len(s)-1]
    fmt.Println(s, len(s), cap(s))
}

but the output showed:

[0 1 2 4] 4 5 [0 1 2 4 4] 5 5

As I know, slice will be passed to a function call as reference type, why it is not able to modify it?

  • 5
    A slice is **not** a reference type, not really. – Milo Christiansen Oct 18 '17 at 03:53
  • 1
    Also, possible duplicate of: [Golang append an item to a slice](https://stackoverflow.com/questions/20195296/golang-append-an-item-to-a-slice). – Milo Christiansen Oct 18 '17 at 03:56
  • A slice is not a reference type, though [it does use a pointer (or something functionally equivalent) to avoid wasting memory](https://play.golang.org/p/8CBxmyBJjl). This means that the memory is shared between the two slices, but the lengths and even the caps may differ. They're essentially two different items. You can read more about slices in the Go blog entry "Go Slices: usage and internals", particularly [this section](https://blog.golang.org/go-slices-usage-and-internals#TOC_4.). –  Oct 18 '17 at 04:42

3 Answers3

5

Slice holds three values:

1) pointer to underlying array

2) length

3) capacity

When you pass slice to a function, you are passing a copy of all three of those values. Therefore, you cannot change length and capacity, but since you have the pointer to the underlying array you can change values inside the array.

Akavall
  • 82,592
  • 51
  • 207
  • 251
2

Slice is not a pointer type. Under the hood slice consists of 3 values: length, capacity and pointer to the array. When you pass it by value, you get copies of length and capacity - you can change them for you. Changes to array will be visible outside of the function.

And if produces such results

Eugene Lisitsky
  • 12,113
  • 5
  • 38
  • 59
0

It's important to note that YES you can indeed change the length and capacity of a Slice or Map within a function when they are passed as parameters. However, those changes aren't visible outside of the function. When you lengthen a slice inside the function call, you're modifying a copy of the length variable that the slice holds. Memory wise, you can modified the slice but when you iterate over it after the function call you'll only be able to look at values up to the original length.

Mutating Algorithm
  • 2,604
  • 2
  • 29
  • 66