1、切片是一种引用类型,当引用改变其中元素的值时,其他所有引用都会改变该值
func main(){
a := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
s1 := a[3:7]
s2 := s1[0:5]
s2[1] = 97
fmt.Println(string(a))
fmt.Println(string(s1))
fmt.Println(string(s2))
}
//运行结果
abcdafghij
dafg
dafgh
//注,s1、s2共享同一个底层数组,但他们可以看到的底层数组的不同部分。
//当两个切片共享同一个底层数组时,若其中一个切片改变了该底层数组的共享部分,另一部分也能感知到。
2、设slice := make([]int, len, cap), 若slice1 := slice[i:j],则slice0的长度为: j - i, 容量为: k - i;
3、使用len()获取元素个数,使用cap()获取容量;
4、声明切片
(1) var a []dataType
(2) a := make([]dataType, len, cap)
5、创建切片:
(1)make函数: make([]datatype, len, cap)。该切片底层数组的长度为cap;
(2)切片字面量,例:slice := []string{"Red", "Blue", "Green", "Yellow", "Pink"} 。该种方法创建的切片长度和容量由元素的个数确定。使用切片字面量时,可以设置初始长度和容量,例: slice := []string{99: ""}
6、nil和空切片
(1)nil切片:var slice [] 则slice为nil切片,长度和容量均为0。若函数返回值类型为切片,但函数运行时发生异常,可以返回nil;
(2)空切片:① slice := make([]int, 0), ② slice := []int{};
7、若切片的底层数组没有足够的可用空间,append函数会创建一个新的底层数组,并将被引用的现有的值复制到新数组里,再追加新的值:
func main(){
slice := []int{10,20,30,40}
newSlice := append(slice, 50)
newSlice[1] = 100
fmt.Println( slice, len(slice), cap(slice) )
fmt.Println( newSlice, len(newSlice), cap(newSlice) )
}
//运行结果:
[10 20 30 40] 4 4
[10 100 30 40 50] 5 8
函数append会智能地处理底层数组的容量增长。在切片容量小于1000时,容量总是成倍地增加。当元素个数超过1000时,每次增加25%;
8、若多个slice指向相同底层数组,其中一个改变会影响全部;
9、声明Slice:
(1) var a []dataType
(2) a := make([]dataType, len, cap)
10、 给切片添加元素, 使用append函数,第一个参数为要追加元素的切片,后面的参数为追加的元素,当追加元素后,元素个数不超过容量时,地址不变,超过后地址改变
func main(){
s1 := make([]int, 3, 6)
fmt.Printf("%v, %p\n", s1, s1)
s1 = append(s1, 2,3,4)
fmt.Printf("%v, %p\n", s1, s1)
s1 = append(s1, 5,6,7)
fmt.Printf("%v, %p\n", s1, s1)
}
//运行结果:
[0 0 0], 0xc00008a030
[0 0 0 2 3 4], 0xc00008a030
[0 0 0 2 3 4 5 6 7], 0xc000050060
11、切片的第三个索引
切片的第三个索引是用来控制切片的容量
设 newSlice = slice[i:j:k],则newSlice的
长度:j - i
容量:k - i
func main(){
source := []string{ "Apple", "Orange", "Plum", "Banana", "Grape" }
slice := source[2:3:4]
fmt.Println( source, len(source), cap(source) )
fmt.Println( slice, len(slice), cap(slice) )
}
// 运行结果:
[Apple Orange Plum Banana Grape] 5 5
[Plum] 1 2
允许限制新切片的容量,为底层数组提供了一定的保护,可以更好地控制追加操作。可强制让新切片的第一个append操作创建新的底层数组,与原有的底层数组分离,可以安全地进行后续修改
func main(){
source := []string{ "Apple", "Orange", "Plum", "Banana", "Grape" }
slice := source[2:3:3]
slice = append(slice, "Wiki")
slice2 := source[3:4:5]
slice2 = append(slice2, "Egg")
fmt.Println( source, len(source), cap(source) )
fmt.Println( slice, len(slice), cap(slice) )
fmt.Println( slice2, len(slice2), cap(slice2) )
}
//运行结果:
[Apple Orange Plum Banana Egg] 5 5
[Plum Wiki] 2 2
[Banana Egg] 2 2