006.Go语言中的切片

目录

1.初识切片

2.切片遍历

3.切片扩容

4.切片扩容原理

5.通过数组创建切片

6.引用传递

7.浅拷贝和深拷贝


1.初识切片

/*
概念:

	切片是一组长度不固定的相同类型数据集合;切片是不存储数据的,是靠底层的数组存储数据;

声明格式:

	var 切片名称 []数据类型

注意:

	1.切片不能存储的数据不能超过切片长度
	2.var 切片名称 []数据类型 声明的未赋值时等于nil,make创建的未赋值时不等于nil
*/
func main() {

	//1.普通方式
	var s1 []int // 或者定义时直接初始化 var s1 = []int {1, 2, 3, 4, 5}
	fmt.Println(len(s1), cap(s1)) // 0 0
	if s1 == nil {
		fmt.Println("切片为空") //切片为空
	}
	s1 = []int{1, 2, 3, 4, 5}
	fmt.Println(len(s1), cap(s1)) // 5 5
	fmt.Printf("s1:%d,数据类型:%T\n", s1, s1) //s1:[1 2 3 4 5],数据类型:[]int

	//2.简化方式
	s2 := []int{6, 6, 6, 8, 8, 8}
	fmt.Printf("s2:%d,数据类型:%T\n", s2, s2) //s2:[6 6 6 8 8 8],数据类型:[]int

	//3.make方式   make([]T,len,cap) 切片类型,切片长度,切片容量
	s3 := make([]string, 3, 5)
	if s3 == nil { //s3不等于nil,不会进来
		fmt.Println("切片为空")
	}
	fmt.Println(s3)
	s3 = []string{"张三", "李四", "王五"}
	fmt.Println(s3)
	//s3[3] = "赵六" // panic: runtime error: index out of range [3] with length 3
}

2.切片遍历

func main() {
	slice := []string{"张三", "李四", "王五"}
	//1.fori方式
	for i := 0; i < len(slice); i++ {
		fmt.Printf("i=%d,v=%s\n", i, slice[i])
	}
	fmt.Println("=================")
	//2.for方式
	for i := range slice {
		fmt.Printf("i=%d,v=%s\n", i, slice[i])
	}
	//3.forr方式
	fmt.Println("=================")
	for i, v := range slice {
		fmt.Printf("i=%d,v=%s\n", i, v)
	}
}

3.切片扩容

        append(切片,数据列表)

func main() {
	slice := make([]int, 0, 5)
	// slice[0] = 3 赋值不能超过切片长度,会报索引越界

	//1.普通扩容
	slice = append(slice, 1, 2)
	fmt.Println(slice)

	//2.解构切片扩容...
	slice2 := []int{3, 4, 5}
	slice = append(slice, slice2...)
	fmt.Println(slice)
}

4.切片扩容原理

/*
切片扩容后:
	长度变为扩容后的长度;长度如果没超过当前容量,容量不变,内存地址也不变;
如果切片长度超过当前容量,且切片长度小于1024:容量×2,内存地址发生改变;
如果切片长度超过当前容量,且切片长度大于1024:容量×1.25,内存地址发生改变;
*/
func main() {
	slice := []int{1, 2, 3, 4, 5}
	fmt.Printf("len:%d,cap:%d,addr:%p\n", len(slice), cap(slice), slice) //len:5,cap:5,addr:0xc00000e360
	slice = append(slice, 6, 7)
	fmt.Printf("len:%d,cap:%d,addr:%p\n", len(slice), cap(slice), slice) //len:7,cap:10,addr:0xc00001a1e0
	slice = append(slice, 8, 9)
	fmt.Printf("len:%d,cap:%d,addr:%p\n", len(slice), cap(slice), slice) //len:9,cap:10,addr:0xc00001a1e0
	slice = append(slice, 10, 11, 12)
	fmt.Printf("len:%d,cap:%d,addr:%p\n", len(slice), cap(slice), slice) //len:12,cap:20,addr:0xc0000220a0
}

5.通过截取数组创建切片

/*
	slice := arr[start:end] 包头不包尾
	长度=切片的数据数量
	容量=数组长度-start
*/
func main() {
	arr := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	fmt.Println(arr)

	s1 := arr[0:5]
	fmt.Printf("s1:%v,数据类型:%T,len:%d,cap:%d\n", s1, s1, len(s1), cap(s1))//s1:[1 2 3 4 5],数据类型:[]int,len:5,cap:10

	s2 := arr[3:8]
	fmt.Printf("s2:%v,数据类型:%T,len:%d,cap:%d\n", s2, s2, len(s2), cap(s2))//s2:[4 5 6 7 8],数据类型:[]int,len:5,cap:7

	s3 := arr[5:]
	fmt.Printf("s3:%v,数据类型:%T,len:%d,cap:%d\n", s3, s3, len(s3), cap(s3))//s3:[6 7 8 9 10],数据类型:[]int,len:5,cap:5

	s4 := arr[:]
	fmt.Printf("s4:%v,数据类型:%T,len:%d,cap:%d\n", s4, s4, len(s4), cap(s4))//s4:[1 2 3 4 5 6 7 8 9 10],数据类型:[]int,len:10,cap:10
	
}

6.引用传递

/*
	引用传递:变量赋值,新的变量会指向原有变量的内存地址,新旧切片修改会相互影响
*/
func main() {
	s1 := []int{1, 2, 3, 4, 5}
	s2 := s1
	fmt.Println("s1", s1) //s1 [1 2 3 4 5]
	fmt.Println("s2", s2) //s2 [1 2 3 4 5]
	fmt.Println("===========")
	s2[0] = 100
	fmt.Println("s1", s1) //s1 [100 2 3 4 5]
	fmt.Println("s2", s2) //s2 [100 2 3 4 5]
}

7.浅拷贝和深拷贝

        浅拷贝:拷贝的是数据的地址;引用类型都是浅拷贝

        深拷贝:拷贝的是数据本身;值类型的数据都是深拷贝

/*
切片是浅拷贝,在6中有实现;
切片通过copy方法实现深拷贝:copy(目标对象,源对象)
*/
func main() {
	s1 := []int{1, 2, 3, 4}
	s2 := make([]int, 4, 4)
	fmt.Println(s1, s2) //[1 2 3 4] [0 0 0 0]
	copy(s2, s1)
	fmt.Println(s1, s2) //[1 2 3 4] [1 2 3 4]
	s1[0] = 10
	fmt.Println(s1, s2) //[10 2 3 4] [1 2 3 4],通过copy实现了切片的深拷贝
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值