How could I iterate through the slice and pass somewhere the slice except the current element? Seems append() function modifies the underlying slice as we could see in documentation. But anyway I still don't know how to reach this.
func main() {
args := []string{ "2", "3", "8" }
for i, _ := range args {
fmt.Println(append(args[:i], args[i+1:]...)) // or pass to function
}
fmt.Println(args)
}
result:
[3 8]
[3 8]
[3 8]
[3 8 8] // it is args now
what I expect:
[3 8]
[2 8]
[2 3]
I already saw this Why does append() modify the provided slice? (See example)
but what is the Capacity of the slice is the secret for me, and I dont understand why did I exceed it.
The append built-in function appends elements to the end of a slice. If it has sufficient capacity, the destination is resliced to accommodate the new elements. If it does not, a new underlying array will be allocated. Append returns the updated slice.
Appending to nil slice: As we know that zero value slice type is nil and the capacity and the length of such type of slice is 0. But with the help of append function, it is possible to append values to nil slice.
The function takes the name of the slice to append to and the element(s) to append to the slice as the arguments. The function will return a slice with the original values and the new ones appended to the slice.
Two slices can be concatenated using append method in the standard golang library.
Performance is the big reason. Creating a new slice and copying all the elements over to it is expensive, so the slice code doesn't copy without good reason. However, if you exceed the slice's capacity, it grows by a suitable amount by copying the underlying slice. That means that the slice that's returned from append
may not be the same slice you passed in.
The preferred way to use is:
args = append(args, newarg)
If you take a subslice, the capacity stays the same but your view into the slice changes. That means the missing elements are still there but outside the bounds of the new slice.
This explains the odd output of your code. You're printing the result of append
each time but not storing that result, which means args
isn't the same as what you printed.
The initial args
slice is 3 elements big. For each index i
- which is to say for 0
, 1
and 2
- you take a subslice args[:i]
and append all the elements of the remainder of the array args[i+1:]
to it. That means that for:
i args[:i] args[i+1]... Result args
0 {} {"3", "8"} {"3", "8"} {"3", "8", "8"}
1 {"3"} {"8"} {"3", "8"} {"3", "8", "8"}
2 {"3", "8"} {} {"3", "8"} {"3", "8", "8"}
tl;dr you should always save the result of append
, and if you want to make a copy so you can change it then make a copy yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With