Reputation: 901
I have this code:
// The input param is A := []int{3, 4, 5, 3, 7}
func someFunc(A []int) int {
...
ways := 0
i := 0
for i < len(A) {
if i+1 == len(A) || i == len(A) {
fmt.Println("break")
break
}
tempA := A // copy the slice by value
fmt.Println("A: ", A)
fmt.Println("tempA: ", A)
fmt.Println()
newArr = remove(tempA, i)
if isAesthetic(newArr) {
ways++
}
i++
}
...
}
func remove(slice []int, s int) []int {
return append(slice[:s], slice[s+1:]...)
}
Cosole output:
A: [3 4 5 3 7]
tempA: [3 4 5 3 7]
A: [4 5 3 7 7]
tempA: [4 5 3 7 7]
A: [4 3 7 7 7]
tempA: [4 3 7 7 7]
A: [4 3 7 7 7]
tempA: [4 3 7 7 7]
The variable A
also changes while I just copy it by value into tempA
. And also it is append()
function, why the slice that used to append tempA
also changed?
Upvotes: 3
Views: 2563
Reputation: 4204
The type []T
is a slice
with elements of type T
. What is a slice
, then?
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).
The rectangle on left is the slice descriptor. The descriptor has 3 fields i.e., a pointer to the array, length, and capacity of array segment it is pointing to. Now, the pointer is pointing to a backing array on the right that actually stores the elements.
Suppose, you have a slice:
x := make([]byte, 5, 5)
Then it'd point to a backing array [5]byte
as you can also see in the image.
Now, if you do:
y := x
thinking that would copy, but it wouldn't. It'd just create a new slice descriptor pointing to the same backing array that x
was pointing to.
Hence, there's a built-in called copy which would help you copy (exactly what you want)
The copy built-in function copies elements from a source slice into a destination slice.
With copy
you also get a new backing array that your destination site is pointing to.
To know more about slices, read this.
Upvotes: 3
Reputation: 1
You need to utilize the copy
function:
package main
import "fmt"
func main() {
a := []int{3, 4, 5, 3, 7}
// bad
b := a
// good
c := make([]int, len(a))
copy(c, a)
// CHANGES b and a!
b = append(b[:1], b[2:]...)
// c stays the same, a is messed up
// [3 5 3 7 7] [3 5 3 7] [3 4 5 3 7]
fmt.Println(a, b, c)
}
https://golang.org/pkg/builtin#copy
Upvotes: 0
Reputation: 44647
A slice variable of type []T
, also called slice header, describes a contiguous section of a backing array. It is stored separately from the array data.
You can imagine it as a struct containing the length and a pointer to a certain item of the array (not necessarily the first one).
When you assign the value of a slice variable, you are actually assigning the length and pointer held by the slice header. So tempA
ends up referencing the same backing array as A
. Then indexing either will access the same underlying array item.
Recommended reading: https://blog.golang.org/slices
Upvotes: 3