切片是一种复合类型,可以是数组也可以是字符串

接下来是一个简单切片使用示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package main

import "fmt"

func slienceInfo(slience []int, str string) {
	fmt.Println("\n", str, "的长度是:", len(slience))
	fmt.Println(str, "的大小是:", cap(slience), "\n")
	for i, v := range slience {
		fmt.Println(str, "下标", i, "是", v)
	}
}

func main() {
	//定义一个数组
	var arr [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

	//打印一下
	for _, v := range arr {
		fmt.Println("arr element is", v)
	}

	//获取数组 arr 从0 到下标为5(不包含下标5) 的一个切片
	mySlice := arr[:5]
	slienceInfo(mySlice, "mySlice")

	//声明一个包含5个元素的数组切片 此时会创建一个匿名数组
	elementSlience := []int{1, 2, 2, 3, 4}
	slienceInfo(elementSlience, "elementSlience")

	//声明一个默认值0,长度5,预留长度10的切片
	emptySlience := make([]int, 5, 10)
	slienceInfo(emptySlience, "emptySlience")

	//向切片中添加元素 这时数组的长度和占用内存是一致的
	emptySlience = append(emptySlience, 1, 2, 3, 4, 5)
	//如果超过分配的内存,会动态分配足够的内存空间
	//	emptySlience = append(emptySlience, 1, 2, 3, 4, 5)
	slienceInfo(emptySlience, "emptySlience2")

	mySlice = append(mySlice, emptySlience...)
	slienceInfo(mySlice, "mySlice2")

  //内容复制  
	slice1 := []int{1, 2, 3, 4, 5}
	slice2 := []int{6, 6, 6}
	//从slice2复制前三个元素到slice1当中,不同长度的按照较小的来
	copy(slice1, slice2)
	slienceInfo(slice2, "slice")

}

从示例中可以看出切片是动态分配内存大小的,我总结了一下几条规律

  1. 当切片源于一个已有的数组时,切片长度取决于截取的长度,切片分配的内存大小和源数组占用的内存大小一样
  2. 当直接生成一个切片数组时,可以定义长度和预留内存
  3. 当切片超出分配内存大小时,系统将会再分配一块足够大的内存

通常如果直到业务中明确的数组极限长度的时候,就分配足够大的内存,以缓解系统不断计算分配内存的压力,典型的空间换时间