Reputation: 1278
I have a repeating list of values which I want to re-use when initializing several arrays like that:
package main
import (
"fmt"
)
func main() {
var i = []int{1, 2, 3}
var a = []int{2, i..., 3}
fmt.Println(a)
}
This code above gives the following error:
./prog.go:9:20: syntax error: unexpected ..., expecting comma or }
I wanted to use the spread ...
operator but this does not seem to be possible while initializing an array.
Am I missing something here or spreading is not allowed?
Upvotes: 6
Views: 7543
Reputation: 418435
You can only use ...
with a slice when passing it to a variadic function. See Spec: Passing arguments to ... parameters.
So for example you could use it when passing it to append()
:
var i = []int{1, 2, 3}
a := append([]int{2}, i...)
a = append(a, 3)
fmt.Println(a)
Which outputs (try it on the Go Playground):
[2 1 2 3 3]
Alternatively the above can be written in one line:
a := append(append([]int{2}, i...), 3)
Do note that this may be compact, it's not necessarily efficient as it may create and copy multiple backing arrays under the hood.
To ensure a single allocation, you could use make()
with capacity provided, for example:
a := make([]int, 0, 2+len(i))
a = append(a, 2)
a = append(a, i...)
a = append(a, 3)
Try this one on the Go Playground.
Yet another solution is to use copy()
if you have the slice preallocated (either with make()
or using indices in the compositle literal):
a := []int{2, 4: 3}
copy(a[1:], i)
Try this one on the Go Playground. The disadvantage here is that the index (4: 3
) must be constant and can't be something like 1 + len(i)
. If you'd want to preallocate the slice (e.g. make([]int, 2+len(i))
), you can't combine that with a composite literal to list elements.
Upvotes: 12