首页 > 其他分享 >go语言基础-切片

go语言基础-切片

时间:2023-04-13 11:24:46浏览次数:33  
标签:语言 s2 fmt cap len 切片 Println go

0x00 切片

切片(Slice)是一个拥有相同类型元素的可变长度的序列。它是基于数组类型做的一层封装。它非常灵活,支持自动扩容。
切片是一个引用类型,它的内部结构包含地址、长度和容量。切片一般用于快速地操作一块数据集合。

0x00 切片的定义

切片的声明:

var name []T
//name:表示变量名
//T:表示切片中的元素类型

eg:

func main() {
	// 声明切片类型
	var a []string              //声明一个字符串切片
	var b = []int{}             //声明一个整型切片并初始化
	var c = []bool{false, true} //声明一个布尔切片并初始化
	var d = []bool{false, true} //声明一个布尔切片并初始化
	fmt.Println(a)              //[]
	fmt.Println(b)              //[]
	fmt.Println(c)              //[false true]
	fmt.Println(a == nil)       //true
	fmt.Println(b == nil)       //false
	fmt.Println(c == nil)       //false
	// fmt.Println(c == d)   //切片是引用类型,不支持直接比较,只能和nil比较
}

0x01 切片的长度和容量

切片拥有自己的长度和容量,我们可以通过使用内置的len()函数求长度,使用内置的cap()函数求切片的容量。

0x02 切片的表达式

切片表达式从字符串、数组、指向数组或切片的指针构造子字符串或切片。它有两种变体:一种指定low和high两个索引界限值的简单的形式,另一种是除了low和high索引界限值外还指定容量的完整的形式。

0x00 简单的切片表达式

切片的底层就是一个数组,所以我们可以基于数组通过切片表达式得到切片。 切片表达式中的low和high表示一个索引范围(左包含,右不包含),也就是下面代码中从数组a中选出1<=索引值<4的元素组成切片s,得到的切片长度=high-low,容量等于得到的切片的底层数组的容量。

func main() {
	a := [5]int{1, 2, 3, 4, 5}
	s := a[1:3]  // s := a[low:high]
	fmt.Printf("s:%v len(s):%v cap(s):%v\n", s, len(s), cap(s))
}

//输出
//s:[2 3] len(s):2 cap(s):4


a[2:]  // 等同于 a[2:len(a)]
a[:3]  // 等同于 a[0:3]
a[:]   // 等同于 a[0:len(a)]

其中对于数组或字符串,如果0 <= low <= high <= len(a),则索引合法,否则就会索引越界(out of range)。

对切片再执行切片表达式时(切片再切片),high的上限边界是切片的容量cap(a),而不是长度。常量索引必须是非负的,并且可以用int类型的值表示;对于数组或常量字符串,常量索引也必须在有效范围内。如果low和high两个指标都是常数,它们必须满足low <= high。如果索引在运行时超出范围,就会发生运行时panic。

func main() {
	a := [5]int{1, 2, 3, 4, 5}
	s := a[1:3]  // s := a[low:high]
	fmt.Printf("s:%v len(s):%v cap(s):%v\n", s, len(s), cap(s))
	s2 := s[3:4]  // 索引的上限是cap(s)而不是len(s)
	fmt.Printf("s2:%v len(s2):%v cap(s2):%v\n", s2, len(s2), cap(s2))
}

//输出:
//	s:[2 3] len(s):2 cap(s):4
//	s2:[5] len(s2):1 cap(s2):1

0x01 使用make()函数构造切片

我们上面都是基于数组来创建的切片,如果需要动态的创建一个切片,我们就需要使用内置的make()函数。

make([]T, size, cap)
//T:切片的元素类型
//size:切片中元素的数量
//cap:切片的容量

0x02 切片的本质

切片的本质就是对底层数组的封装,它包含了三个信息:底层数组的指针、切片的长度(len)和切片的容量(cap)。

要检查切片是否为空,请始终使用len(s) == 0来判断,而不应该使用s == nil来判断。

0x03 切片不能直接比较

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

var s1 []int         //len(s1)=0;cap(s1)=0;s1==nil
s2 := []int{}        //len(s2)=0;cap(s2)=0;s2!=nil
s3 := make([]int, 0) //len(s3)=0;cap(s3)=0;s3!=nil

0x03 切片遍历

func main() {
	s := []int{1, 3, 5}

	for i := 0; i < len(s); i++ {
		fmt.Println(i, s[i])
	}

	for index, value := range s {
		fmt.Println(index, value)
	}
}

0x04 append()方法给切片添加元素

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

func main(){
	var s []int
	s = append(s, 1)        // [1]
	s = append(s, 2, 3, 4)  // [1 2 3 4]
	s2 := []int{5, 6, 7}  
	s = append(s, s2...)    // [1 2 3 4 5 6 7]
}

var s []int
s = append(s, 1, 2, 3)
//通过var声明的零值切片可以在append()函数直接使用,无需初始化。

每个切片会指向一个底层数组,这个数组的容量够用就添加新增元素。当底层数组不能容纳新增的元素时,切片就会自动按照一定的策略进行“扩容”,此时该切片指向的底层数组就会更换。“扩容”操作往往发生在append()函数调用时,所以我们通常都需要用原变量接收append函数的返回值。

0x05 使用copy()函数复制切片

Go语言内建的copy()函数可以迅速地将一个切片的数据复制到另外一个切片空间中,copy()函数的使用格式如下:

copy(destSlice, srcSlice []T)

//srcSlice: 数据来源切片
//destSlice: 目标切片
func main() {
	// copy()复制切片
	a := []int{1, 2, 3, 4, 5}
	c := make([]int, 5, 5)
	copy(c, a)     //使用copy()函数将切片a中的元素复制到切片c
	fmt.Println(a) //[1 2 3 4 5]
	fmt.Println(c) //[1 2 3 4 5]
	c[0] = 1000
	fmt.Println(a) //[1 2 3 4 5]
	fmt.Println(c) //[1000 2 3 4 5]
}

0x06 从切片中删除元素

Go语言中并没有删除切片元素的专用方法,我们可以使用切片本身的特性来删除元素。 代码如下:

func main() {
	// 从切片中删除元素
	a := []int{30, 31, 32, 33, 34, 35, 36, 37}
	// 要删除索引为2的元素
	a = append(a[:2], a[3:]...)
	fmt.Println(a) //[30 31 33 34 35 36 37]
}

要从切片a中删除索引为index的元素,操作方法是a = append(a[:index], a[index+1:]...)

参考博客:
https://www.liwenzhou.com/posts/Go/06_slice/#autoid-2-1-1(李文周师傅)

标签:语言,s2,fmt,cap,len,切片,Println,go
From: https://www.cnblogs.com/MeetA/p/17312809.html

相关文章

  • go语言基础-map
    0x00mapmap是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用。0x00map的定义go语言当中map的定义map[KeyType]ValueType//KeyType:表示键的类型 //ValueType:表示键对应的值的类型。map类型的变量默认初始值为nil,需要使用make()函数来......
  • go语言基础-数组
    0x00数组go语言中的数组声明的基本语法://定义一个长度为3元素类型为int的数组avara[3]intvar数组名称[元素数量]元素类型比如:vara[5]int,数组的长度必须是常量,并且长度是数组类型的一部分。一旦定义,长度不能变。[5]int和[10]int是不同的类型。vara[3]intvar......
  • go语言基础-变量和常量
    0x00标识符与关键字0x01标识符go语言中的标识符是由数字,字母和_(下划线)组成的,并且只能由字母和_开头。eg:abc,_,_abc,abc10x02关键字关键字是指编程语言中定义好的具有特殊意义的标识符。(关键字和保留字都不建议作为变量名)go语言中常用的25个关键字breakdefault......
  • go语言基础-基本数据结构
    0x00基本数据结构go语言中,除了基本的整型、浮点型、布尔型、字符串外,还有数组、切片、结构体、函数、map、通道(channel)等。0x00整型(int)整型分为以下两个大类:按长度分为:int8、int16、int32、int64对应的无符号整型:uint8、uint16、uint32、uint64。其中,uint8就是我们熟知的......
  • Django 对实体的增删改查样例
    classUserInfo(models.Model):"""人员信息"""user_id=models.CharField(max_length=20,primary_key=True,blank=False,verbose_name='人员ID')user_name=models.CharField(max_length=200,blank=Fal......
  • 如何用Golang处理每分钟100万个请求
    用Golang处理每分钟100万个请求转载请注明来源:https://janrs.com/9yaq面临的问题在我设计一个分析系统中,我们公司的目标是能够处理来自数百万个端点的大量POST请求。web网络处理程序将收到一个JSON文档,其中可能包含许多有效载荷的集合,需要写入AmazonS3,以便我们的地图还原系统随后......
  • golang 标准库bytes有哪些知识点
    标准库bytes是Go语言中用来操作字节串(byteslice)的包。以下是bytes包的一些重要知识点:bytes.Buffer类型:这是bytes包中最常用的类型之一。Buffer类型表示一个缓冲区,可以用来动态地构建字节串,也可以用来读取字节串。bytes.NewBuffer()函数:这是一个用来创建bytes.Buffer类型的......
  • c语言贪吃蛇(1)地图实现
    采用循环输出来实现按照行和列的顺序两次for循环输出。代码:结果: ......
  • django 配置admin 数据管理,增加数据批量上传下载功能
    在使用django-admin带来直接管理数据库带来的便利的同时,我们希望数据能批量上传,为了达到此目的,我们需要django-admin-export 模块一、安装模块pip3installdjango-import-export-ihttps://mirrors.aliyun.com/pypi/simple/二、settings.py注册模块INSTALLED_APPS=......
  • 使用 LoRA 和 Hugging Face 高效训练大语言模型
    在本文中,我们将展示如何使用大语言模型低秩适配(Low-RankAdaptationofLargeLanguageModels,LoRA)技术在单GPU上微调110亿参数的FLAN-T5XXL模型。在此过程中,我们会使用到HuggingFace的Transformers、Accelerate和PEFT库。通过本文,你会学到:如何搭建开发环......