我试图将切片[1,2]和切片[3,4]结合起来。我如何在围棋中做到这一点?
我试着:
append([]int{1,2}, []int{3,4})
但有:
cannot use []int literal (type []int) as type int in append
然而,文档似乎表明这是可能的,我错过了什么?
slice = append(slice, anotherSlice...)
我试图将切片[1,2]和切片[3,4]结合起来。我如何在围棋中做到这一点?
我试着:
append([]int{1,2}, []int{3,4})
但有:
cannot use []int literal (type []int) as type int in append
然而,文档似乎表明这是可能的,我错过了什么?
slice = append(slice, anotherSlice...)
当前回答
我认为重要的是要指出并知道,如果目标片(你追加的片)有足够的容量,追加将“原地”发生,通过重切片目的地(重切片增加它的长度,以便能够容纳可追加的元素)。
这意味着如果目标是通过切片一个更大的数组或切片创建的,其中有超出结果切片长度的额外元素,它们可能会被覆盖。
为了演示,请看这个例子:
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)
输出(在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]
我们创建了一个长度为10的“支持”数组a。然后我们通过将这个数组切片来创建x目标切片,y切片使用复合文字[]int{3,4}创建。现在,当我们将y追加到x时,结果是预期的[1 2 3 4],但可能令人惊讶的是,后备数组a也发生了变化,因为x的容量为10,这足以将y追加到它,因此x被重新分割,这也将使用相同的后备数组,append()将复制y的元素到那里。
如果你想避免这种情况,你可以使用一个完整的切片表达式
a[low : high : max]
它构造一个切片,并通过将其设置为Max - low来控制结果切片的容量。
查看修改后的示例(唯一的区别是我们像这样创建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)
输出(在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]
正如你所看到的,我们得到了相同的x结果,但支持数组a没有改变,因为x的容量“只有”2(多亏了完整的切片表达式a[:2:2])。为了追加,分配了一个新的后备数组它可以存储x和y的元素,这与a是不同的。
其他回答
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. 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. 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. 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 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. The length of the slice is therefore the number of arguments bound to the final parameter and may differ for each call site.
你问题的答案是Go编程语言规范中的示例s3:= append(s2, s0…)例如,
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: 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"...)
我认为重要的是要指出并知道,如果目标片(你追加的片)有足够的容量,追加将“原地”发生,通过重切片目的地(重切片增加它的长度,以便能够容纳可追加的元素)。
这意味着如果目标是通过切片一个更大的数组或切片创建的,其中有超出结果切片长度的额外元素,它们可能会被覆盖。
为了演示,请看这个例子:
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)
输出(在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]
我们创建了一个长度为10的“支持”数组a。然后我们通过将这个数组切片来创建x目标切片,y切片使用复合文字[]int{3,4}创建。现在,当我们将y追加到x时,结果是预期的[1 2 3 4],但可能令人惊讶的是,后备数组a也发生了变化,因为x的容量为10,这足以将y追加到它,因此x被重新分割,这也将使用相同的后备数组,append()将复制y的元素到那里。
如果你想避免这种情况,你可以使用一个完整的切片表达式
a[low : high : max]
它构造一个切片,并通过将其设置为Max - low来控制结果切片的容量。
查看修改后的示例(唯一的区别是我们像这样创建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)
输出(在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]
正如你所看到的,我们得到了相同的x结果,但支持数组a没有改变,因为x的容量“只有”2(多亏了完整的切片表达式a[:2:2])。为了追加,分配了一个新的后备数组它可以存储x和y的元素,这与a是不同的。
在第二片之后加点:
// vvv
append([]int{1,2}, []int{3,4}...)
这和其他变进函数一样。
func foo(is ...int) {
for i := 0; i < len(is); i++ {
fmt.Println(is[i])
}
}
func main() {
foo([]int{9,8,7,6,5}...)
}
Append()函数和展开运算符
可以使用标准golang库中的append方法连接两个片。这类似于变进函数的运算。所以我们需要用…
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)
}
上述代码的输出是:[1 2 3 4 5 6]