以下Go数组操作有什么作用?

时间:2017-07-20 02:51:57

标签: arrays go

我对以下代码的工作原理感到困惑,尤其是“......”的目的是什么

array = append(array[:i], array[i+1:]...)

4 个答案:

答案 0 :(得分:2)

该行

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 {s}在https://golang.org/ref/spec#Passing_arguments_to_..._parameters中所描述的那样:

  

如果f是具有类型... T的最终参数p的可变参数,那么在f中p的类型等同于类型[] T.如果在没有p的实际参数的情况下调用f,则传递给p的值为nil。否则,传递的值是一个类型为[] T的新切片,其中包含一个新的基础数组,其连续元素是实际参数,所有这些都必须可赋值给T

Playground

答案 1 :(得分:1)

class Foo(object):

   def __init__(foo=None, bar=None):
     self.foo = foo
     self.bar = bar

foo = Foo()
foo.foo = 29

正在删除索引为array = append(array[:i], array[i+1:]...)

的元素

但要指出的另一件事是切片由底层数组支持。例如:

i

结果:

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)
}

goplayground

在基础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}};另一个[1,2,3]留在原地。

即使你得到一个切片的不同副本,底层数组也是相同的*,如果必须复制整个底层数组,这会使得附加一个更有效的操作!

*如果底层数组超出了它的容量,将分配一个新的更大的数组,旧数组的值将被复制到新数组,但删除元素时不会发生这种情况。

答案 2 :(得分:0)

内置函数append是Variadic函数。

要将slice参数传递给任何可变参数函数,必须使用...

Go lang spec:Passing arguments to ... parameters

  

如果f是具有最终参数类型的可变参数... T,那么在   function该参数等效于[] T类型的参数。在   每次调用f,传递给final参数的参数都是新的   type [] 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]

播放链接:https://play.golang.org/p/_cIk0VcD6w

答案 3 :(得分:0)

...的目的是为了节省您输入单个元素,因为append方法将第一个参数作为slice,然后是要附加的元素的可变数量的参数。

即。你实际上需要调用append as

append(sliceName[:i], array[i+1], array[i+2], array[i+3], array[i+4])

但为了避免输入长元素列表,您可以在切片或数组之后使用...将其作为单个元素进行传播,作为参数传递。