go语言之切片

切片(Slice)是一个拥有相同类型元素的可变长度的序列。它是基于数组类型做的一层封装。它非常灵活,支持自动扩容。

切片是一个引用类型,它的内部结构包含地址长度容量。切片一般用于快速地操作一块数据集合。

1、定义切片并初始化

数组和切片的区别

数组:[n]int

切片:[ ]int

    // 定义切片并且初始化
	s1 := []string{"上海", "呼市", "包头"} //切片
	s3 := []int{1, 3, 5, 7, 9}
	s2 := [3]string{"上海", "呼市", "包头"} //数组
	fmt.Printf("%T\n", s2)
	fmt.Printf("%T\n", s1)
	fmt.Printf("%T\n", s3)
	fmt.Println(s1 == nil)
	fmt.Println(s3 == nil)
	fmt.Printf("s1的长度:%d,s1的容量:%d\n", len(s1), cap(s1))
	fmt.Printf("s3的长度:%d,s3的容量:%d\n", len(s3), cap(s3))

2、数组得到切片

切片:指向底层数组。

切片的长度就是它元素的个数

切片的容量是底层数组从切片的第一个元素到最后一个元素的数量;

通过代码理解:

    // 由数组得到切片
	d1 := [...]int{1, 3, 5, 7, 9, 11, 13}
	fmt.Printf("%T\n", d1)
	d2 := d1[0:4] //基于一个数组切割,左包含右不包含=>左闭右开
	fmt.Println(d2)
	d3 := d1[2:5]
	fmt.Println(d3)
	d4 := d1[3:]
	fmt.Println(d4)
	d5 := d1[:]
	fmt.Println(d5)
	fmt.Printf("%T\n", d5)
	// 切片的长度就是元素的个数
	// 切片的容量是底层数组的容量,从切片开始的下标指向数组的最后一个下表才是切片容量
	fmt.Printf("d2的长度:%d,d2的容量:%d\n", len(d2), cap(d2))
	fmt.Printf("d3的长度:%d,d3的容量:%d\n", len(d3), cap(d3))

3、切片再切割

切片是一个引用类型,都指向底层数组,底层数组的值发生变化切片也会改变

    //切片再切割
	d6 := d4[3:]
	fmt.Printf("d6的长度:%d,d6的容量:%d\n", len(d6), cap(d6))
	fmt.Println("d6", d6)
	//切片是一个引用类型,都指向了底层的一个数组。
	d1[6] = 88
	fmt.Println("d4", d4)
	fmt.Println("d6", d6)
	d4[3] = 99
	fmt.Println("d4", d4)
	fmt.Println("d6", d6)

4、使用make构造切片

make()可以动态的创建切片

    s1 := make([]int, 5, 10)
	fmt.Printf("s1=%v len(s1)=%d cap(s1):%d\n", s1, len(s1), cap(s1))
	s2 := make([]int, 0, 10)
	fmt.Printf("s2=%v len(s2)=%d cap(s2):%d", s2, len(s2), cap(s2))
	fmt.Println()

5、切片赋值

    //切片的赋值
	s3 := []int{1, 3, 5}
	s4 := s3
	fmt.Println(s3, s4)
	s3[0] = 100
	fmt.Println(s3, s4)

6、切片遍历

    //切片遍历
	//1、索引遍历
	for i := 0; i < len(s3); i++ {
		fmt.Println(s3[i])
	}
	//2、for range 循环遍历
	for i, v := range s3 {
		fmt.Println(i, v)
	}

7、append()函数为切片追加元素

Go语言的内建函数append()可以为切片动态添加元素。 可以一次添加一个元素,可以添加多个元素,也可以添加另一个切片中的元素(后面加…)。

    s1 := []string{"北京", "上海", "广州"}
	fmt.Printf("s1=%v,len(s1)=%d,cap(s1)=%d\n", s1, len(s1), cap(s1))
	// s1[4] = "呼市"  //错误写法,会导致编译报错:索引越界

	//调用append函数必须用原来的切片变量接收返回值
	//append追加元素,原来的底层数组放不下的时候,Go底层就会把底层数组换一个
	//必须用原来变量接收append的返回值
	s1 = append(s1, "深圳")
	fmt.Printf("s1=%v,len(s1)=%d,cap(s1)=%d\n", s1, len(s1), cap(s1))
	s1 = append(s1, "杭州", "成都")
	fmt.Printf("s1=%v,len(s1)=%d,cap(s1)=%d\n", s1, len(s1), cap(s1))
	ss := []string{"武汉", "西安", "苏州"}
	s1 = append(s1, ss...)
	fmt.Printf("s1=%v,len(s1)=%d,cap(s1)=%d\n", s1, len(s1), cap(s1))

	//关于append删除某个切片中的某个元素
	a1 := [...]int{1, 3, 5, 7, 9, 11, 13, 15, 17}
	d1 := a1[:]
	//删掉索引为1,2,3的三个数
	d1 = append(d1[:1], d1[4:]...)
	fmt.Println(d1)
	fmt.Println(a1)

8、copy()复制切片

   a1 := []int{1, 3, 5}
	a2 := a1 //赋值
	a3 := make([]int, 3, 5)
	copy(a3, a1) //a1来源切片,a3目标切片
	fmt.Println(a1, a2, a3)
	a1[0] = 100
	fmt.Println(a1, a2, a3)
	//将a1中索引为1的3这个元素删掉
	a1 = append(a1[:1], a1[2:]...)
	fmt.Println(a1)
	fmt.Println(cap(a1))

	x1 := [...]int{1, 3, 5} //数组
	s1 := x1[:]             //切片
	fmt.Println(s1, len(s1), cap(s1))
	//1、切片不保存具体的值
	//2、切片对应一个底层数组
	//3、底层数组都是占用一块连续的内存
	fmt.Printf("%p\n", &s1[1])
	s1 = append(s1[:1], s1[2:]...) //修改了底层数组
	fmt.Printf("%p\n", &s1[1])
	fmt.Println(s1, len(s1), cap(s1))
	fmt.Println(x1)

你可能感兴趣的:(golang,开发语言,后端)