Concatenate two slices in Go
我正在尝试组合切片
我试过:
1 | append([]int{1,2}, []int{3,4}) |
但得到:
1 | cannot use []int literal (type []int) as type int in append |
然而,文档似乎表明这是可能的,我遗漏了什么?
1 | slice = append(slice, anotherSlice...) |
在第二个切片后添加点:
1 2 | //---------------------------vvv append([]int{1,2}, []int{3,4}...) |
这和其他变量函数一样。
1 2 3 4 5 6 7 8 9 | func foo(is ...int) { for i := 0; i < len(is); i++ { fmt.Println(is[i]) } } func main() { foo([]int{9,8,7,6,5}...) } |
Appending to and copying slices
The variadic function
append appends zero or more valuesx tos
of typeS , which must be a slice type, and returns the resulting
slice, also of typeS . The valuesx are passed to a parameter of
type...T whereT is the element type ofS and the respective
parameter passing rules apply. As a special case, append also accepts
a first argument assignable to type[]byte with a second argument of
string type followed by... . This form appends the bytes of the
string.
1
2
3
4
5
6 append(s S, x ...T) S // T is the element type of S
s0 := []int{0, 0}
s1 := append(s0, 2) // append a single element s1 == []int{0, 0, 2}
s2 := append(s1, 3, 5, 7) // append multiple elements s2 == []int{0, 0, 2, 3, 5, 7}
s3 := append(s2, s0...) // append a slice s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}Passing arguments to ... parameters
If
f is variadic with final parameter type...T , then within the
function the argument is equivalent to a parameter of type[]T . At
each call off , the argument passed to the final parameter is a new
slice of type[]T whose successive elements are the actual arguments,
which all must be assignable to the typeT . The length of the slice is
therefore the number of arguments bound to the final parameter and may
differ for each call site.
您的问题的答案是go编程语言规范中的示例
1 | s := append([]int{1, 2}, []int{3, 4}...) |
没有什么与其他答案相反,但我发现文档中的简短解释比它们中的示例更容易理解:
func append
func append(slice []Type, elems ...Type) []Type 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. It is therefore necessary to store the
result of append, often in the variable holding the slice itself:
1
2 slice = append(slice, elem1, elem2)
slice = append(slice, anotherSlice...)As a special case, it is legal to append a string to a byte slice,
like this:
1 slice = append([]byte("hello"),"world"...)
我认为重要的是要指出并知道,如果目标切片(附加到的切片)有足够的容量,则通过重新单击目标(重新单击以增加其长度,以便能够容纳可附加的元素),附加将"就地"发生。
这意味着,如果目标是通过切片一个更大的数组或切片创建的,而该数组或切片的附加元素超过了结果切片的长度,那么它们可能会被覆盖。
要演示,请参见以下示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | a := [10]int{1, 2} fmt.Printf("a: %v ", a) x, y := a[:2], []int{3, 4} fmt.Printf("x: %v, y: %v ", x, y) fmt.Printf("cap(x): %v ", cap(x)) x = append(x, y...) fmt.Printf("x: %v ", x) fmt.Printf("a: %v ", a) |
输出(在游乐场上尝试):
1 2 3 4 5 | a: [1 2 0 0 0 0 0 0 0 0] x: [1 2], y: [3 4] cap(x): 10 x: [1 2 3 4] a: [1 2 3 4 0 0 0 0 0 0] |
我们创建了一个长度为
如果要避免这种情况,可以使用具有
1 | a[low : high : max] |
它构造一个切片,并通过将其设置为
参见修改后的示例(唯一的区别是我们创建了这样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | a := [10]int{1, 2} fmt.Printf("a: %v ", a) x, y := a[:2:2], []int{3, 4} fmt.Printf("x: %v, y: %v ", x, y) fmt.Printf("cap(x): %v ", cap(x)) x = append(x, y...) fmt.Printf("x: %v ", x) fmt.Printf("a: %v ", a) |
输出(在游乐场上尝试)
1 2 3 4 5 | a: [1 2 0 0 0 0 0 0 0 0] x: [1 2], y: [3 4] cap(x): 2 x: [1 2 3 4] a: [1 2 0 0 0 0 0 0 0 0] |
如你所见,我们得到了相同的
append()函数和spread运算符
在标准的Golang库中,可以使用
1 2 3 4 5 6 7 8 9 10 11 12 | package main import ( "fmt" ) func main() { x := []int{1, 2, 3} y := []int{4, 5, 6} z := append([]int{}, append(x, y...)...) fmt.Println(z) } |
output of the above code is: [1 2 3 4 5 6]
如果
如果调用
否则,传递的值是一个新的
给定函数和调用
1 2 3 | func Greeting(prefix string, who ...string) Greeting("nobody") Greeting("hello:","Joe","Anna","Eileen") |