go语言 – 附加切片(slice)元素

我们已经知道数组的长度是固定的,不能增加。切片长度是动态的,可以使用append函数将新元素添加到片中。append函数的定义是func append(s []T, x...T) []T

函数定义中的x...T,表示可变参数,参数类型为T,传入的参数数量可变,这种函数称为可变参数函数。

不过有一个问题可能困扰着你。如果切片的底层是数组,数组本身的长度是固定的,那么切片长度为什么可以是动态的呢?

当新元素被添加到切片中时,就会创建一个新的数组。将现有数组的元素复制到这个新数组中,并返回这个新数组的一个新切片引用。

现在新切片的容量变大了(具体增加多少,由go决定)。

来看一个例子:

package main

import (  
    "fmt"
)

func main() {  
    cars := []string{"Ferrari", "Honda", "Ford"}
    fmt.Println("cars:", cars, "has old length", len(cars), "and capacity", cap(cars)) //capacity of cars is 3
    cars = append(cars, "Toyota")
    fmt.Println("cars:", cars, "has new length", len(cars), "and capacity", cap(cars)) //capacity of cars is doubled to 6
}

在上述方案中,切片cars的初始容量为3,给这个切片增加一个新元素,将append(cars,"Toyota")返回的切片,重新分配给cars。现在cars的容量增加了一倍,变成了6辆。以上程序的输出为

cars: [Ferrari Honda Ford] has old length 3 and capacity 3  
cars: [Ferrari Honda Ford Toyota] has new length 4 and capacity 6  

切片类型的零值为nil。值为nil的切片,其长度和容量为0。可以使用append函数将值追加到nil切片。

package main

import (  
    "fmt"
)

func main() {  
    var names []string //切片的零值是nil
    if names == nil {
        fmt.Println("slice is nil going to append")
        names = append(names, "John", "Sebastian", "Vinay")
        fmt.Println("names contents:",names)
    }
}

在上面的程序中,名称是nil,我们在名称后面附加了3个字符串。程序的输出是

slice is nil going to append  
names contents: [John Sebastian Vinay]  

也可以使用...符号将一个切片附加到另一个切片。关于此...操作符后续变参函数部分会有更多介绍。

package main

import (  
    "fmt"
)

func main() {  
    veggies := []string{"potatoes","tomatoes","brinjal"}
    fruits := []string{"oranges","apples"}
    food := append(veggies, fruits...)
    fmt.Println("food:",food)
}

输出: food: [potatoes tomatoes brinjal oranges apples]



浙ICP备17015664号 浙公网安备 33011002012336号 联系我们 网站地图  
@2019 qikegu.com 版权所有,禁止转载