在Go中串联两个切片

本文翻译自: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 values x to s of type S , which must be a slice type, and returns the resulting slice, also of type S . 所述可变参数函数append追加的零个或更多个值xs类型的S ,它必须是一个切片类型,并返回型也所得到的切片, S The values x are passed to a parameter of type ...T where T is the element type of S and the respective parameter passing rules apply. x传递给类型为...T的参数,其中TS的元素类型,并且适用各个参数传递规则。 As a special case, append also accepts a first argument assignable to type []byte with a second argument of string 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 of f , 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 type T . 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] : 请参见修改后的示例(唯一的不同是我们像这样创建xx = 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 . 这样做追加,一个新的背衬阵列被分配,可以同时存储的元素xy ,这是从不同的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类型的可变参数,则在fp的类型等效于[]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")
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值