我对以下代码的工作方式感到困惑,尤其是“...”的目的是什么
array = append(array[:i], array[i+1:]...)
线
a = append(a[:i], a[i+1:]...)
通过删除
i
中位置a
处的项目,通过组合从0到i(不包括)和从i+1到末尾的项目来创建一个新切片。
你的第二个问题是
...
的目的是什么。 append
接受一个切片作为第一个参数,以及无限数量的参数,所有参数的类型都是 assignable 到它的元素的类型。
append
定义为
func append(slice []Type, elems ...Type) []Type
写作
a = append(a[:i], a[i+1:]...)
相当于写作
a = append(a[:i], a[i+1], a[i+2], a[i+3], a[i+4]) //and so on, until the end of the slice.
使用
a[i+1:]...
基本上是一种速记语法,正如 Go 规范在 https://golang.org/ref/spec#Passing_arguments_to_..._parameters: 中所描述的那样
如果 f 是可变的,其最终参数 p 的类型为 ...T,则在 f 中,p 的类型等同于类型 []T。如果调用 f 而 p 没有实际参数,则传递给 p 的值为 nil。否则,传递的值是一个 []T 类型的新切片,带有一个新的底层数组,其连续元素是实际参数,所有这些都必须可分配给 T
array = append(array[:i], array[i+1:]...)
正在删除索引处的元素
i
但要指出的另一件事是 slice 由底层数组支持。例如:
package main
import (
"fmt"
)
func main() {
myArray := [6]int {1,2,3,4,5,6}
mySlice := myArray[:]
fmt.Println("myArray before append: ", myArray)
i := 3
mySlice = append(mySlice[:i], mySlice[i+1:]...)
fmt.Println("mySlice after append: ", mySlice)
fmt.Println("myArray after append: ", myArray)
}
结果:
myArray before append: [1 2 3 4 5 6]
mySlice after append: [1 2 3 5 6]
myArray after append: [1 2 3 5 6 6]
在基础
[1,2,3]
中,数据永远不会移动到任何地方,而由[5,6]
给出的b[i+1]
被附加到[1,2,3]
,从而覆盖了[3,4]
;另一个[6]
留在原地。
即使您获得切片的不同副本,底层数组也将是相同的*,这使得追加操作比必须复制整个底层数组更有效!
*如果底层数组超出其容量,将分配一个新的更大的数组,并将旧数组中的值复制到新数组,但删除元素时永远不会发生这种情况。
Built-in func append 是 Variadic Function.
要将 slice 参数传递给任何可变参数函数,您必须使用
...
Go 语言规范:Passing arguments to ... parameters
如果 f 是可变的,最终参数类型为 ...T,则在 function 参数等同于 []T 类型的参数。在 每次调用 f,传递给最终参数的参数都是一个新的 []T 类型的切片,其连续元素是实际参数, 所有这些都必须可以分配给类型 T。切片的长度是 因此,绑定到最终参数的参数数量可能 每个呼叫站点都不同。
这条线会给你一个结果值删除位置
i
.
array = append(array[:i], array[i+1:]...)
比方说,我们有
array := []int{1, 2, 3, 4, 5, 6, 7}
i := 3
fmt.Println("Original slice:", array)
part1 := array[:i]
part2 := array[i+1:]
fmt.Println("part1:", part1)
fmt.Println("part2:", part2)
array = append(array[:i], array[i+1:]...)
fmt.Println("Result slice:", array)
输出:
Original slice: [1 2 3 4 5 6 7]
part1: [1 2 3]
part2: [5 6 7]
Result slice: [1 2 3 5 6 7]
...
的目的是避免您键入单个元素,因为 append
方法将第一个参数作为切片,然后为要附加的元素使用可变数量的参数。
即你实际上需要调用 append as
append(sliceName[:i], array[i+1], array[i+2], array[i+3], array[i+4])
但是为了避免键入一长串元素,您可以在切片或数组之后简单地使用
...
将其作为单个元素展开以作为参数传递。