本文翻译自:Concatenate two slices in Go
I'm trying to combine the slice [1, 2]
and the slice [3, 4]
. 我正在尝试将切片[1, 2]
和切片[3, 4]
[1, 2]
结合在一起。 How can I do this in Go? 如何在Go中执行此操作?
I tried: 我试过了:
append([]int{1,2}, []int{3,4})
but got: 但得到:
cannot use []int literal (type []int) as type int in append
However, the documentation seems to indicate this is possible, what am I missing? 但是, 文档似乎表明这是可能的,我想念的是什么?
slice = append(slice, anotherSlice...)
#1楼
参考:https://stackoom.com/question/16AuP/在Go中串联两个切片
#2楼
Add dots after the second slice: 在第二个切片之后添加点:
//---------------------------vvv
append([]int{1,2}, []int{3,4}...)
This is just like any other variadic function. 就像任何其他可变参数函数一样。
func foo(is ...int) {
for i := 0; i < len(is); i++ {
fmt.Println(is[i])
}
}
func main() {
foo([]int{9,8,7,6,5}...)
}
#3楼
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
. 所述可变参数函数append
追加的零个或更多个值x
到s
类型的S
,它必须是一个切片类型,并返回型也所得到的切片,S
。 The valuesx
are passed to a parameter of type...T
whereT
is the element type ofS
and the respective parameter passing rules apply. 值x
传递给类型为...T
的参数,其中T
是S
的元素类型,并且适用各个参数传递规则。 As a special case, append also accepts a first argument assignable to type[]byte
with a second argument ofstring
type followed by...
. 作为一种特殊情况,append还接受可分配给[]byte
类型的第一个参数,并带有string
类型的第二个参数,后跟...
This form appends the bytes of the string. 这种形式附加了字符串的字节。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
. 如果f
是最终参数类型为...T
可变参数,则在函数内,参数等效于[]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
. 在f
每次调用中,传递给最终参数的参数是[]T
类型的新切片,其连续元素是实际参数,所有这些参数都必须可分配给T
类型。 The length of the slice is therefore the number of arguments bound to the final parameter and may differ for each call site. 因此,切片的长度是绑定到最终参数的参数个数,并且对于每个调用站点可能有所不同。
The answer to your question is example s3 := append(s2, s0...)
in the Go Programming Language Specification . 您的问题的答案是Go编程语言规范中的示例s3 := append(s2, s0...)
。 For example, 例如,
s := append([]int{1, 2}, []int{3, 4}...)
#4楼
Nothing against the other answers, but I found the brief explanation in the docs more easily understandable than the examples in them: 没有其他答案,但是我发现文档中的简短解释比其中的示例更容易理解:
func append 功能附加
func append(slice []Type, elems ...Type) []Type
The append built-in function appends elements to the end of a slice.func append(slice []Type, elems ...Type) []Type
附加内置函数将元素附加到切片的末尾。 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: 因此,有必要将append的结果存储在通常包含切片本身的变量中: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: 作为一种特殊情况,将字符串附加到字节片是合法的,如下所示:
slice = append([]byte("hello "), "world"...)
#5楼
I think it's important to point out and to know that if the destination slice (the slice you append to) has sufficient capacity, the append will happen "in-place", by reslicing the destination (reslicing to increase its length in order to be able to accommodate the appendable elements). 我认为必须指出并知道,如果目标切片(您附加到的切片)具有足够的容量,则通过对目标进行切片(为了增加长度而进行切片),可以“就地”进行追加能够容纳附加元素)。
This means that if the destination was created by slicing a bigger array or slice which has additional elements beyond the length of the resulting slice, they may get overwritten. 这意味着,如果目标是通过切片更大的数组或切片而创建的,而该数组或切片具有超出结果切片长度之外的其他元素,则它们可能会被覆盖。
To demonstrate, see this example: 为了演示,请参见以下示例:
a := [10]int{1, 2}
fmt.Printf("a: %v\n", a)
x, y := a[:2], []int{3, 4}
fmt.Printf("x: %v, y: %v\n", x, y)
fmt.Printf("cap(x): %v\n", cap(x))
x = append(x, y...)
fmt.Printf("x: %v\n", x)
fmt.Printf("a: %v\n", a)
Output (try it on the Go Playground ): 输出(在Go Playground上尝试):
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]
We created a "backing" array a
with length 10
. 我们创建了a
长度为10
的“后备”数组a
。 Then we create the x
destination slice by slicing this a
array, y
slice is created using the composite literal []int{3, 4}
. 然后,我们创建了x
通过切片目的地切片这a
阵列, y
使用复合字面创建切片[]int{3, 4}
Now when we append y
to x
, the result is the expected [1 2 3 4]
, but what may be surprising is that the backing array a
also changed, because capacity of x
is 10
which is sufficient to append y
to it, so x
is resliced which will also use the same a
backing array, and append()
will copy elements of y
into there. 现在,当我们将y
附加到x
,结果是预期的[1 2 3 4]
,但是令人惊讶的是,后备数组a
也发生了变化,因为x
容量为10
,足以将y
附加到其上,因此x
进行切片,该切片也将使用相同a
支持数组,并且append()
将y
元素复制到该数组中。
If you want to avoid this, you may use a full slice expression which has the form 如果要避免这种情况,可以使用具有以下形式的完整切片表达式
a[low : high : max]
which constructs a slice and also controls the resulting slice's capacity by setting it to max - low
. 它构造一个切片,并通过将其设置为max - low
来控制所得切片的容量。
See the modified example (the only difference is that we create x
like this: x = a[:2:2]
: 请参见修改后的示例(唯一的不同是我们像这样创建x
: x = a[:2:2]
:
a := [10]int{1, 2}
fmt.Printf("a: %v\n", a)
x, y := a[:2:2], []int{3, 4}
fmt.Printf("x: %v, y: %v\n", x, y)
fmt.Printf("cap(x): %v\n", cap(x))
x = append(x, y...)
fmt.Printf("x: %v\n", x)
fmt.Printf("a: %v\n", a)
Output (try it on the Go Playground ) 输出(在Go Playground上尝试)
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]
As you can see, we get the same x
result but the backing array a
did not change, because capacity of x
was "only" 2
(thanks to the full slice expression a[:2:2]
). 如您所见,我们得到相同的x
结果,但后备数组a
不变,因为x
容量“仅”为2
(由于完整的切片表达式a[:2:2]
)。 So to do the append, a new backing array is allocated that can store the elements of both x
and y
, which is distinct from a
. 这样做追加,一个新的背衬阵列被分配,可以同时存储的元素x
和y
,这是从不同的a
。
#6楼
append([]int{1,2}, []int{3,4}...)
will work. append([]int{1,2}, []int{3,4}...)
将起作用。 Passing arguments to ...
parameters. 将参数传递给...
参数。
If f
is variadic with a final parameter p
of type ...T
, then within f
the type of p
is equivalent to type []T
. 如果f
是最终参数p
为...T
类型的可变参数,则在f
内p
的类型等效于[]T
类型。
If f
is invoked with no actual arguments for p
, the value passed to p
is nil
. 如果在没有p
实际参数的情况下调用f
,则传递给p
值为nil
。
Otherwise, the value passed is a new slice of type []T
with a new underlying array whose successive elements are the actual arguments, which all must be assignable to T
. 否则,传递的值是[]T
类型的新切片,带有新的基础数组,其连续元素是实际参数,所有这些参数都必须可分配给T
The length and capacity of the slice is therefore the number of arguments bound to p
and may differ for each call site. 因此,切片的长度和容量是绑定到p
的参数的数量,并且对于每个调用站点可能有所不同。
Given the function and calls 给定功能和调用
func Greeting(prefix string, who ...string)
Greeting("nobody")
Greeting("hello:", "Joe", "Anna", "Eileen")