Reputation: 944
I'm wondering whether there is a way to pass a slice of the appropriate size to a function that is expecting an array?
For example, is there a reason I shouldn't be allowed to do the following?
func p(arr [4]int) {
for _, v := range arr {
fmt.Print(v)
}
}
func main() {
data := make([]int, 10)
for i, _ := range data {
data[i] = i
}
p(data[0:4]) // error
}
I know that I can just create a copy:
arr := [4]int{}
copy(arr[:], data)
p(arr)
But isn't that just creating an unnecessary copy? (since I'm guessing that another copy of arr
will have to be made on the stack)
Upvotes: 0
Views: 986
Reputation: 127751
For example, is there a reason I shouldn't be allowed to do the following?
Yes, there is. [4]int
is just a flat sequence of four integers. When you pass it to the function, they are copied, so modifications inside a function won't affect original value. The following code prints 1 2 3 4
both times.
func change(arr [4]int) {
arr[1] = 100
}
func prn(arr [4]int) {
for _, v := range arr {
print(v, " ")
}
println()
}
func main() {
x := [4]int{1, 2, 3, 4}
prn(x)
change(x)
prn(x)
}
However, a slice is a pointer to an array of some size (called capacity of the slice) and a length - two pointer-sized numbers. When you pass a slice to a function, you essentially pass a reference to the underlying array, so you can change it inside the function. The following program prints 1 2 3 4
and then 1 100 3 4
:
func change(arr []int) {
arr[1] = 100
}
func prn(arr []int) {
for _, v := range arr {
print(v, " ")
}
println()
}
func main() {
x := []int{1, 2, 3, 4}
prn(x)
change(x)
prn(x)
}
So, in fact, internal representation of slices and arrays are different, and one cannot be used instead of another and vice versa. You have to copy slice contents to another array.
Of course, there are no technical difficulties which prevent Go from doing such conversion automatically (create an array implicitly and copy slice contents to it and pass it to the function). However, Go language designers made deliberate decision to abstain from implicit conversions as much as possible. If you really need this operation, you can do it yourself, it is not that hard.
Upvotes: 3