当前位置:网站首页>【Golang】快速复习指南QuickReview(二)——切片slice
【Golang】快速复习指南QuickReview(二)——切片slice
2022-06-23 18:52:00 【DDGarfield】
在上一篇【Golang】快速复习指南QuickReview(一)——字符串string的字符串翻转代码实现中,提到了切片,切片在golang中是很重要的数据类型。说到切片,就不得不提数组,但是数组的长度是固定的并且数组长度属于类型的一部分,所以数组有很多的局限性。而切片(Slice)是可变长度的,其实切片是基于数组类型做了一层封装,所以切片会指向一个底层数组。切片新增元素,当切片指向的底层数组能够容纳,则直接新增元素,当底层数组不能容纳新增的元素时,切片就会自动按照一定的策略进行“扩容”,此时该切片指向的底层数组就会更换。
切片有两个非常重要的属性,长度(len),容量(cap),前者是切片已经包含的元素数量,后者是切片的首指针(第一个元素)指向的底层数组索引至底层数组最后一个元素的长度。
切片Slice
1.C#的泛型集合List
根据切片的特性,博主类比的是C#中泛型集合,也会有类似长度与容量等属性,包括自动扩容,但是博主并不清楚扩容算法是否一致,有兴趣的朋友可以自行查阅。
//实例化 初始化
List<string> ls = new List<string> { "北京", "上海", "广州", "深圳" };
//输出容量与长度
Console.WriteLine($"the capacity of citylist is {ls.Capacity},and the length of citylist is {ls.Count}");
//新增元素
ls.Add("成都");
//再次输出容量与长度
Console.WriteLine($"the capacity of citylist is {ls.Capacity},and the length of citylist is {ls.Count}");
//删除元素
ls.Remove("成都");
//再次输出容量与长度
Console.WriteLine($"the capacity of citylist is {ls.Capacity},and the length of citylist is {ls.Count}");
//遍历元素
foreach (string city in ls)
{
}
the capacity of citylist is 4,and the length of citylist is 4
the capacity of citylist is 8,and the length of citylist is 5
the capacity of citylist is 8,and the length of citylist is 4
另外在C#中还提供了很多很多扩展方法来操作泛型集合,这里提一些常用的。
//添加多个元素
public void AddRange(IEnumerable<T> collection);
//删除所有
public void Clear();
//按条件删除
public int RemoveAll(Predicate<T> match);
//按索引进行范围删除
public void RemoveRange(int index, int count);
//遍历操作
public void ForEach(Action<T> action);
//判断是否存在某元素
public bool Contains(T item);
//按条件判断是否存在
public bool Exists(Predicate<T> match);
//按条件查找指定元素
public List<T> FindAll(Predicate<T> match);
//翻转集合
public void Reverse();
//转换数组
public T[] ToArray();
2.Golang中的切片
切片没有在C#中的泛型集合那么方便,具有一些硬性条件,例如分配空间,操作函数也少,但是也顺便减少了记忆量,记住下面的一些常规操作,基本就能看懂源码里对切片进行的相关操作。
1. 初始化-新增-复制
1.1 定义不初始化
//定义不初始化-这个定义不初始化的称为-零值切片
var citySlice0 []string
1.2 定义且初始化
//定义且初始化
var citySlice1 = []string{}
var citySlice2 = []string{"北京", "上海", "广州", "深圳"}
1.3 make定义并初始化
//make定义并初始化
citySlice := make([]string, 4, 10)
fmt.Printf("the citySlice is %v\n", citySlice)
1.4 容量与长度
由内置函数cap()len()提供:
//输出容量和长度
fmt.Printf("the capacity of citySlice is %v,and the length of citySlice is %v \n", cap(citySlice), len(citySlice))
1.5 新增
由内置函数append()提供:
//新增元素
citySlice = append(citySlice, "北京", "上海", "广州", "深圳")
fmt.Printf("the citySlice is %v\n", citySlice)
fmt.Printf("the capacity of citySlice is %v,and the length of citySlice is %v \n", cap(citySlice), len(citySlice))
//var声明的零值切片最简单的方式便是通过append函数直接使用,无需初始化
var intSliceA []int
intSliceA = append(intSliceA, 1, 2, 3)
fmt.Printf("the intSliceA is %v \n", intSliceA)//[1 2 3]
//切片是引用类型 简单的赋值就出现如下结果
intSliceB := intSliceA
intSliceB[0] = 0
fmt.Printf("the intSliceA is %v \n", intSliceA) //[0,2,3]
1.6 复制
由内置函数copy()提供:
//为了不影响赋值操作,只要复制切片才能达到预期的效果, 但是把一个切片复制给另一个切片,目的切片需要分配空间
intSliceC := make([]int, 4, 5)
copy(intSliceC, intSliceA)
fmt.Printf("the intSliceC is %v \n", intSliceC) //[0 2 3 0] 第4个元素0,是因为分配了空间,都是零值
intSliceC[0] = 10
fmt.Printf("the intSliceA is %v \n", intSliceA) //[0 2 3]
fmt.Printf("the intSliceC is %v \n", intSliceC) //[10 2 3 0]
1.7 汇总
//定义不初始化-这个定义不初始化的称为-零值切片
var citySlice0 []string
//定义且初始化
var citySlice1 = []string{}
var citySlice2 = []string{"北京", "上海", "广州", "深圳"}
//make定义并初始化
citySlice := make([]string, 4, 10)
fmt.Printf("the citySlice is %v\n", citySlice)
//输出容量和长度
fmt.Printf("the capacity of citySlice is %v,and the length of citySlice is %v \n", cap(citySlice), len(citySlice))
//新增元素
citySlice = append(citySlice, "北京", "上海", "广州", "深圳")
fmt.Printf("the citySlice is %v\n", citySlice)
fmt.Printf("the capacity of citySlice is %v,and the length of citySlice is %v \n", cap(citySlice), len(citySlice))
//新增元素
citySlice = append(citySlice, "成都", "武汉")
fmt.Printf("the citySlice is %v\n", citySlice)
fmt.Printf("the capacity of citySlice is %v,and the length of citySlice is %v \n", cap(citySlice), len(citySlice))
//var声明的零值切片最简单的方式便是通过append函数直接使用,无需初始化
var intSliceA []int
intSliceA = append(intSliceA, 1, 2, 3)
fmt.Printf("the intSliceA is %v \n", intSliceA)//[1 2 3]
//切片是引用类型 简单的赋值就出现如下结果
intSliceB := intSliceA
intSliceB[0] = 0
fmt.Printf("the intSliceA is %v \n", intSliceA) //[0,2,3]
//为了不影响赋值操作,只要复制切片才能达到预期的效果, 但是把一个切片复制给另一个切片,目的切片需要分配空间
intSliceC := make([]int, 4, 5)
copy(intSliceC, intSliceA)
fmt.Printf("the intSliceC is %v \n", intSliceC) //[0 2 3 0] 第4个元素0,是因为分配了空间,都是零值
intSliceC[0] = 10
fmt.Printf("the intSliceA is %v \n", intSliceA) //[0 2 3]
fmt.Printf("the intSliceC is %v \n", intSliceC) //[10 2 3 0]
the citySlice is [ ]
the capacity of citySlice is 10,and the length of citySlice is 4
the citySlice is [ 北京 上海 广州 深圳]
the capacity of citySlice is 10,and the length of citySlice is 8
the citySlice is [ 北京 上海 广州 深圳 成都 武汉]
the capacity of citySlice is 10,and the length of citySlice is 10
the intSliceA is [1 2 3]
the intSliceA is [0 2 3]
the intSliceC is [0 2 3 0]
the intSliceA is [0 2 3]
the intSliceC is [10 2 3 0]
2. 切
切片之所以叫切片,着重点在切
“数组上切,就成了切片,在切片上切,就成了切切片(#^.^#),当然不是,还是叫切片。”
//the intSliceC is [10 2 3 0]
//从索引1切到最后
intSliceD := intSliceC[1:]
fmt.Printf("the intSliceD is %v \n", intSliceD) // [2 3 0]
//从索引1切到索引2,按照数学知识就是左闭右开[1,3)
intSliceE := intSliceC[1:3]
fmt.Printf("the intSliceE is %v \n", intSliceE) //[2 3]
//从索引0切到n-1 0,1,2
intSliceF := intSliceC[:3]
fmt.Printf("the intSliceF is %v \n", intSliceF) //[10 2 3]
//再次验证长度与容量
fmt.Printf("the capacity of intSliceF is %v,and the length of intSliceF is %v \n", cap(intSliceF), len(intSliceF))
//
fmt.Printf("the intSliceC is %v \n", intSliceC) //[10 2 3 0]
the intSliceD is [2 3 0]
the intSliceE is [2 3]
the intSliceF is [10 2 3]
the capacity of intSliceF is 5,and the length of intSliceF is 3
the intSliceC is [10 2 3 0]
3. 删除
golang是没有提供切片的直接删除函数,但是是可以利用内置的append()函数
func append(slice []Type, elems ...Type) []Type
ps:参数中使用可变参数
... Type,是类似于C#中可变参数params T[] x,C#内部是转换成数组处理,Golang内部转换为了切片。有那么一点差别,就是如果参数传切片,后面需要加...,其余用法与C#一致
intSliceC = append(intSliceC[:1], intSliceC[2:]...)
fmt.Printf("the intSliceC is %v \n", intSliceC) // [10 2 0]
fmt.Printf("the capacity of intSliceC is %v,and the length of intSliceC is %v \n", cap(intSliceC), len(intSliceC))
the intSliceC is [10 2 0]
the capacity of intSliceC is 5,and the length of intSliceC is 3
4. 判断切片是否为空
只能使用len函数,不能使用nil。
len(s) == 0
5. 遍历
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)
}
0 1
1 3
2 5
0 1
1 3
2 5
再次强调:这个系列并不是教程,如果想系统的学习,博主可推荐学习资源。
边栏推荐
- SAVE: 软件分析验证和测试平台
- Application de JDBC dans les essais de performance
- Technology sharing | wvp+zlmediakit realizes streaming playback of camera gb28181
- 打新债 要求 打新债安全吗
- Daily question brushing record (II)
- Application of JDBC in performance test
- 八大误区,逐个击破(终篇):云难以扩展、定制性差,还会让管理员失去控制权?
- logstash启动 -r 参数
- OHOS LTS 3.0移植到RaspberryPi 4B
- Development of block hash quiz game system (DAPP)
猜你喜欢

Daily question brushing record (II)

Activity registration | introduction to mongodb 5.0 sequential storage features

宝安区航城街道领导一行莅临联诚发参观调研

每日刷题记录 (二)

Check four WiFi encryption standards: WEP, WPA, WPA2 and WPA3

墨天轮访谈 | IvorySQL王志斌—IvorySQL,一个基于PostgreSQL的兼容Oracle的开源数据库

Eight misunderstandings, broken one by one (final): the cloud is difficult to expand, the customization is poor, and the administrator will lose control?

直播回顾 | 云原生混部系统 Koordinator 架构详解(附完整PPT)

Helix QAC is updated to 2022.1 and will continue to provide high standard compliance coverage

Live sharing | Tencent cloud mongodb intelligent diagnosis and Performance Optimization Practice
随机推荐
「开源摘星计划」Containerd拉取Harbor中的私有镜像,云原生进阶必备技能
Chaos engineering, learn about it
Activity registration | introduction to mongodb 5.0 sequential storage features
Game asset reuse: a new way to find required game assets faster
打新债 要求 打新债安全吗
Flagai Feizhi: AI basic model open source project, which supports one click call of OPT and other models
OHOS LTS 3.0移植到RaspberryPi 4B
增加双因素认证,不惧密码泄露,更不惧123456
Design of hardware switch with programmable full function rate limiter
Netseer: stream event telemetry notes for programmable data plane
基于 ShardingSphere 的得物数据库中间件平台“彩虹桥”演进之路
Gaussdb (DWS) database intelligent monitoring operation and maintenance service - node monitoring indicators
How to avoid the "black swan" incident in the gene field: a security war behind a preventive "recall"
Programmable, protocol independent software switch (read the paper)
Rstudio 1.4 software installation package and installation tutorial
ZABBIX monitoring - Aruba AP operation data
Save: software analysis, verification and test platform
After the collapse of UST, will the stable currency market pattern usher in new opportunities?
Advanced network accounting notes (6)
The golden nine silver ten, depends on this detail, the offer obtains the soft hand!