切片是一种类似于数组的数据结构,但它可以改变大小。
在引擎盖下,切片使用数组,它们是建立在数组之上的一种抽象,使它们更加灵活和有用(把数组看作是低级别的)。
你使用分片的方式与你在高级语言中使用数组的方式非常相似。
你定义分片的方式与数组类似,省略了长度:
var mySlice []string //a slice of strings
你可以用值来初始化分片:
var mySlice = []string{"First", "Second", "Third"}
//or
mySlice := []string{"First", "Second", "Third"}
你可以使用make() 函数来创建一个特定长度的空片子:
mySlice := make([]string, 3) //a slice of 3 empty strings
你可以从一个现有的片断中创建一个新的片断,将一个或多个项目附加到它上面:
mySlice := []string{"First", "Second", "Third"}
newSlice := append(mySlice, "Fourth", "Fifth")
注意,我们需要把append() 的结果分配给一个新的片断,否则我们会得到一个编译器错误。原来的片断不会被修改,我们会得到一个全新的片断。
你也可以使用copy() 函数来复制一个分片,这样它就不会与另一个分片共享相同的内存,而是独立的:
mySlice := []string{"First", "Second", "Third"}
newSlice := make([]string, 3)
copy(newSlice, mySlice)
如果你要复制的片断没有足够的空间(比原来的片断短),那么只有前几项(直到有空间)会被复制。
你可以从一个数组中初始化一个片断:
myArray := [3]string{"First", "Second", "Third"}
mySlice = myArray[:]
多个片断可以使用同一个数组作为底层数组:
myArray := [3]string{"First", "Second", "Third"}
mySlice := myArray[:]
mySlice2 := myArray[:]
mySlice[0] = "test"
fmt.Println(mySlice2[0]) //"test"
这2个片子现在共享相同的内存,修改一个片子会修改底层数组,并导致从数组生成的另一个片子也被修改。
与数组一样,切片中的每个项目都被存储在内存中的连续位置。
如果你知道你需要对分片进行操作,你可以要求它拥有比最初需要的更多的容量,所以当你需要更多的空间时,空间将是现成的(而不是寻找和移动分片到一个有更多空间的新的内存位置来增长,并通过垃圾收集处理旧的位置)。
我们可以指定容量,给make() 添加第三个参数:
newSlice := make([]string, 0, 10)
//an empty slice with capacity 10
和字符串一样,你可以用这个语法获得一个片断的一部分:
mySlice := []string{"First", "Second", "Third"}
newSlice := mySlice[:2] //get the first 2 items
newSlice2 := mySlice[2:] //ignore the first 2 items
newSlice3 := mySlice[1:3] //new slice with items in position 1-2