go基础——切片slice

package main

import "fmt"

/*
	切片:
	不定长的数组,是引用类型的数据,指向一个底层数组。
*/
func main() {
	//切片的创建和访问
	var s1 []int
	fmt.Println(s1)

	s2 := []int{1, 2, 3, 4}
	fmt.Println(s2)
	s2[0] = 5
	fmt.Println(s2)

	s3 := make([]int, 3)
	/*
		make函数可以创建slice,map,chan这三种引用类型
		第一个参数是类型,第二个参数是长度len,第三个参数是容量cap(这里省略了)
	*/
	fmt.Println(s3)

	//切片扩容append
	s3 = append(s3, 1, 2)
	fmt.Println(s3)
	s3 = append(s3, s2...) //append另一个切片中的元素
	fmt.Println(s3)

	//遍历切片
	for i := 0; i < len(s2); i++ {
		fmt.Println(s2[i])
	}

	for i, v := range s2 {
		fmt.Println(i, v)
	}

	//切片扩容原理
	/*
		新建一个len=3,cap=3的切片
		append两个值时,这时切片指向一个新的cap=6的底层数组,并把前一个数组的值复制给新数组。
		元素个数再次增大超过6时,成倍扩容为cap=12。
		slice本身不存储数据,指向的数组存储数据,切片变化cap靠改变指向的数组实现。
	*/
	sli1 := make([]int, 3)
	fmt.Printf("len:%d,cap:%d,切片地址:%p,数组地址:%p
", len(sli1), cap(sli1), &sli1, sli1)
	sli1 = append(sli1, 1, 2)
	fmt.Printf("len:%d,cap:%d,切片地址:%p,数组地址:%p
", len(sli1), cap(sli1), &sli1, sli1)
	sli1 = append(sli1, 3, 4)
	fmt.Printf("len:%d,cap:%d,切片地址:%p,数组地址:%p
", len(sli1), cap(sli1), &sli1, sli1)

	//在已有array上直接创建slice
	arr := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	sli2 := arr[:5]  //1-5
	sli3 := arr[3:8] //4-8
	sli4 := arr[5:]  //6-10
	sli5 := arr[:]   //1-10
	fmt.Println("arr:", arr)
	fmt.Println("sli2:", sli2)
	fmt.Printf("len:%d,cap:%d,数组地址:%p
", len(sli2), cap(sli2), sli2)
	fmt.Println("sli3:", sli3)
	fmt.Printf("len:%d,cap:%d,数组地址:%p
", len(sli3), cap(sli3), sli3)
	fmt.Println("sli4:", sli4)
	fmt.Printf("len:%d,cap:%d,数组地址:%p
", len(sli4), cap(sli4), sli4)
	fmt.Println("sli5:", sli5)
	fmt.Printf("len:%d,cap:%d,数组地址:%p
", len(sli5), cap(sli5), sli5)
	//更改数组或切片内容
	fmt.Println("=========更改数组==========")
	arr[7] = 100
	fmt.Println("arr:", arr)
	fmt.Println("sli2:", sli2)
	fmt.Println("sli3:", sli3)
	fmt.Println("sli4:", sli4)
	fmt.Println("sli5:", sli5)
	fmt.Println("=========更改切片==========")
	sli2[4] = 200
	fmt.Println("arr:", arr)
	fmt.Println("sli2:", sli2)
	fmt.Println("sli3:", sli3)
	fmt.Println("sli4:", sli4)
	fmt.Println("sli5:", sli5)
	fmt.Println("=========append切片(未超过数组cap)==========")
	sli2 = append(sli2, 0, 0, 0) //修改了数组的5-7位数值
	fmt.Println("arr:", arr)
	fmt.Println("sli2:", sli2)
	fmt.Println("sli3:", sli3)
	fmt.Println("sli4:", sli4)
	fmt.Println("sli5:", sli5)
	fmt.Println("=========append切片(超过数组cap)==========")
	sli4 = append(sli4, 99, 99, 99) //新建了一个底层数组
	sli4[4] = 111                   //再修改sli4不会对原数组有影响了
	fmt.Println("arr:", arr)
	fmt.Println("sli2:", sli2)
	fmt.Println("sli3:", sli3)
	fmt.Print("sli4:", sli4)
	fmt.Printf("	len:%d,cap:%d
", len(sli4), cap(sli4))
	fmt.Println("sli5:", sli5)
}

执行结果

[]
[1 2 3 4]
[5 2 3 4]
[0 0 0]
[0 0 0 1 2]
[0 0 0 1 2 5 2 3 4]
5
2
3
4
0 5
1 2
2 3
3 4
len:3,cap:3,切片地址:0xc0000040f0,数组地址:0xc000012210
len:5,cap:6,切片地址:0xc0000040f0,数组地址:0xc00000a420
len:7,cap:12,切片地址:0xc0000040f0,数组地址:0xc00001a1e0
arr: [1 2 3 4 5 6 7 8 9 10]
sli2: [1 2 3 4 5]
len:5,cap:10,数组地址:0xc00000c1e0
sli3: [4 5 6 7 8]
len:5,cap:7,数组地址:0xc00000c1f8
sli4: [6 7 8 9 10]
len:5,cap:5,数组地址:0xc00000c208
sli5: [1 2 3 4 5 6 7 8 9 10]
len:10,cap:10,数组地址:0xc00000c1e0
=========更改数组==========
arr: [1 2 3 4 5 6 7 100 9 10]
sli2: [1 2 3 4 5]
sli3: [4 5 6 7 100]
sli4: [6 7 100 9 10]
sli5: [1 2 3 4 5 6 7 100 9 10]
=========更改切片==========
arr: [1 2 3 4 200 6 7 100 9 10]
sli2: [1 2 3 4 200]
sli3: [4 200 6 7 100]
sli4: [6 7 100 9 10]
sli5: [1 2 3 4 200 6 7 100 9 10]
=========append切片(未超过数组cap)==========
arr: [1 2 3 4 200 0 0 0 9 10]
sli2: [1 2 3 4 200 0 0 0]
sli3: [4 200 0 0 0]
sli4: [0 0 0 9 10]
sli5: [1 2 3 4 200 0 0 0 9 10]
=========append切片(超过数组cap)==========
arr: [1 2 3 4 200 0 0 0 9 10]
sli2: [1 2 3 4 200 0 0 0]
sli3: [4 200 0 0 0]
sli4:[0 0 0 9 111 99 99 99]     len:8,cap:10
sli5: [1 2 3 4 200 0 0 0 9 10]
原文地址:https://www.cnblogs.com/maxgongzuo/p/15420052.html