go入门学习-切片

本文介绍了Go语言中的切片,它作为数组的抽象,具有长度可变的特性。切片包括长度和容量,可以通过初始化、由数组创建、使用make函数等方式生成。切片可以通过append函数追加元素,并通过copy函数复制内容。切片是引用类型,修改切片会影响到底层数组。文章还展示了切片操作的实际例子,包括切片的创建、追加、拷贝等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

切片(slice)

Go 语言切片是对数组的抽象。

Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大

切片是一个引用类型,他的结构包含 地址,长度,容量

package main

import "fmt"

func main() {
	var s1 []int //申明一个存放int类型元素的切片
	var s2 []string//申明一个string类型元素的切片
	fmt.Println(s1,s2) //空表示没有开辟内存空间
	fmt.Println(s1==nil)//true
	fmt.Println(s2==nil)//true


	//初始化
	s3:=[]int{1,2,3,4}
	s4:=[]string{"四川","重庆","湖南"}
	fmt.Println(s3,s4)
	fmt.Println(s3==nil)//false
	fmt.Println(s4==nil)//false
	//长度和容量
	fmt.Printf("len(s3):%d cap(s3):%d\n",len(s3),cap(s3))
	fmt.Printf("len(s4):%d cap(s4):%d\n",len(s4),cap(s4))

	//由数组得到切片 注意:后面的数字表示长度
	 s5:=[...]int{1,2,3,4,5}
	 s5_1:=s5[0:3] //[1 2 3]
	 s5_2:=s5[:3] //[0:3]  [1 2 3 ]
	 s5_3:=s5[1:] //[0:3]  [2 3 4 5]
	 s5_4:=s5[:]//[0:len(s5)] [1 2 3 4 5]
	 fmt.Println(s5_1,s5_2,s5_3,s5_4)
	 //注:切片的容量是指底层数组的容量
	 fmt.Printf("len(s5_1):%d cap(s5_1):%d\n",len(s5_1),cap(s5_1))//len(s5_1):3 cap(s5_1):5
	 //底层数组从切片的第一个元素到最后元素的数量
	 fmt.Printf("len(s5_3):%d cap(s5_3):%d\n",len(s5_3),cap(s5_3))//len(s5_3):4 cap(s5_3):4


	 //切片再切片
	 s6:=s5_3[3:]
	 fmt.Printf("len(s6):%d cap(s6):%d\n",len(s6),cap(s6))//len(s6):1 cap(s6):1
	 //修改了底层数组;注:切片是引用类型
	 s5[4]=500
	 fmt.Println(s5_3)//[2 3 4 500]
	 fmt.Println(s6)//[500]


	 //make函数创建切片
	 s7:=make([]int,5,10)
	fmt.Printf("s7-%v len(s7):%d cap(s7):%d\n",s7,len(s7),cap(s7)) //s7-[0 0 0 0 0] len(s7):5 cap(s7):10
	
}


在这里插入图片描述

在这里插入图片描述
总结:

  • 切片是指向了一个底层数组
  • 切片的长度就是他元素的个数
  • 切片的容量是底层数组的第一个元素到最后一个元素的数量

切片的本质

切片就是一个框,框柱了一块内存,属于引用类型,真正的数据都是存在底层数组里的

  • 切片之间是不能进行比较的,不能使用==来判断两个切片是否全部等元素,切片唯一合法的比较是和nil比较;一个nil值的切片并没有底层数组,一个nil值的切片长度和容量都是0;但我们不能说一个长度容量都是0的切片一定是nil
package main

import "fmt"

func main() {
	var s1 []int //一个切片在未初始化之前默认为 nil,长度为 0
	  s2:=[]int{}
	  s3:=make([]string,0,0)
	fmt.Printf("s1:%T值为nil 表示没有开辟内存空间  len(s1)=%d  cap(s1)=%d (s1==nil)=%v \n",s1,len(s1),cap(s1),s1==nil)
	fmt.Printf("s2:%T值为0   表示开辟了内存空间    len(s2)=%d  cap(s2)=%d (s2==nil)=%v \n",s2,len(s2),cap(s2),s2==nil)
	fmt.Printf("s3:%T值为0   表示开辟了内存空间    len(s3)=%d  cap(s3)=%d (s3==nil)=%v \n",s3,len(s3),cap(s3),s3==nil)
}

append 和copy

package main

import "fmt"

func main() {
	var numbers []int //申明一个存放int类型元素的切片
	printSlice(numbers)
	/* 允许追加空切片 */
	numbers = append(numbers, 0)
	printSlice(numbers)
	/* 向切片添加一个元素 */
	numbers = append(numbers, 1)
	printSlice(numbers)
	/* 同时添加多个元素 */
	numbers = append(numbers, 2,3,4)
	printSlice(numbers)

	/* 创建切片 numbers1 是之前切片的两倍容量*/
	numbers1 := make([]int, len(numbers), (cap(numbers))*2)

	/* 拷贝 numbers 的内容到 numbers1 */
	copy(numbers1,numbers)
	printSlice(numbers1)
}
func printSlice(x []int){
	fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

append 练习

package main

import "fmt"

func main() {
	s1:=[]string{"北京","上海","深圳"}
	fmt.Printf("s1  len=%d cap=%d slice=%v\n",len(s1),cap(s1),s1)
	//s1[3]="四川"//错误的语法会编译出错,索引越界

	//调用append函数必须用原来的切片变量接收返回值
	s1=append(s1,"四川")
	fmt.Printf("s1  len=%d cap=%d slice=%v\n",len(s1),cap(s1),s1)
	s1=append(s1,"杭州","武汉")
	fmt.Printf("s1  len=%d cap=%d slice=%v\n",len(s1),cap(s1),s1)
	ss:=[]string{"武汉","西安","南京"}
	s1=append(s1,ss...)//...表示拆开
	fmt.Printf("s1  len=%d cap=%d slice=%v\n",len(s1),cap(s1),s1)
}

结果

s1  len=3 cap=3 slice=[北京 上海 深圳]
s1  len=4 cap=6 slice=[北京 上海 深圳 四川]
s1  len=6 cap=6 slice=[北京 上海 深圳 四川 杭州 武汉]
s1  len=9 cap=12 slice=[北京 上海 深圳 四川 杭州 武汉 武汉 西安 南京]


copy练习

package main

import "fmt"

func main() {
	a1:=[]int{1,2,3,4}
	a2:=a1//赋值
	//var a3 []int//nil
	var a3=make([]int,3,3)
	copy(a3,a1)
	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)
}
结果:
[1 2 3 4] [1 2 3 4] [1 2 3]
[100 2 3 4] [100 2 3 4] [1 2 3]
[100 3 4]

注意:copy到目的切片需要定义好长度和容量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值