golang切片简介
目录
创建
创建与初始化
make函数创建
初始化创建
空切片与nil
创建共享底层数组的切片
访问
迭代
不定参数传递
操作
扩容
插入元素
尾部插入
头部插入
中间插入
删除元素
尾部删除
头部删除
中间删除
遍历时删除
切片(slice)是Golang中数组之上的抽象;可按需自动增长与缩小。切片的底层是连续的内存块。
创建
切片本身是一个三个字段的数据结构:
- Data:指向底层数组的指针;
- Len:切片中元素的个数;len(s)获取;
- Cap:切片的容量(不需重新分配内存前,可容纳的元素数量);cap(s)获取;
type SliceHeader struct {Data uintptrLen intCap int
}
创建与初始化
有多种创建切片的方式。
make函数创建
内置的make函数可用于创建切片(长度不能超过容量):
// 创建长度为0,容量为10的切片
s := make([]int, 0, 10)// 创建长度为10(存储的是对应类型的默认值,即0),容量为10的切片
s2 := make([]int, 10)// 获取底层对应数据结构
low:=(*reflect.SliceHeader)(unsafe.Pointer(&s1))
fmt.Printf("Data:%d,Len:%d,Cap:%d\n",low.Data,low.Len,low.Cap)
初始化创建
根据给定的数据,自动创建并初始化切片(与数组的区别是[]中没有长度信息):
// 长度、容量都为3的切片
s := []int{1,2,3}// 长度、容量都为10,最后一个元素为99,其他为默认值0
s2 := []int{9: 99}
空切片与nil
声明时不做任何初始化就会创建一个nil切片;而空切片是底层数组包含0个元素,且没有分配存储空间。nil与空切片都可直接获取长度(len)或追加元素(append)。
// 值为nil的切片
var s []int// 创建空切片
s1 := make([]int, 0)
s2 := []int{}
创建共享底层数组的切片
在已有数组/切片上创建切片为:s = src[low : high : max] ,三个参数意义为
- low为截取的起始下标(含), high为窃取的结束下标(不含high),max为切片保留的原切片的最大下标(不含max);
- 新切片从老切片的low下标元素开始,len = high - low, cap = max - low;high 和 max一旦超出在老切片中越界,就会发生runtime err,slice out of range。
- 没有指定max:max的值为截取对象(数组、切片)的容量。
在已有数组/切片上切出一部分可以生成新的切片,他们共享底层的数组;因此修改一个切片的内容(在不扩容的情况下),会影响到其他共享底层数组的切片:
// 元素范围为[i,j),k限制容量为(k-i)
s := src[i:j:k]// 从i到尾部
s := src[i:]// 从头到j(不包括j)
s := src[:j]// 从头到尾(复制整个切片),但底层数组还是公用的
s := src[:]
访问
切片只能访问其长度范围内的内容,通过下标访问
s[i] = 10
v = s[i]
迭代
切片是一个集合,可以通过range迭代其中的元素:
for index, value := range myS{fmt.Printf("index: %d, value: %d\n", index, value)
}
range返回的第二个值是对应元素的一份副本,不能用于修改;若要修改则需要通过索引:
for index, _ := range myS{myS[index] += 1
}
迭代方式遍历时,不能有其他线程对切片进行操作(添加、或删除元素),否则会引发恐慌。
不定参数传递
切片可直接传递给‘不定参数’,即使空切片也可以:
func NilSliceParam() {var s []stringmultiEle(s...)
}func multiEle(all ...string) {log.Println(all)
}
操作
通过函数append可在切片尾部追加元素;通过copy(dest,src)可复制切片,复制的长度是minimum of len(src) and len(dst)。
可对nil切片追加元素,以及求长度:
var sl []int // nil
if sl == nil{ // truefmt.Println("is nill")
}
fmt.Println(sl) // []
fmt.Println(len(sl)) // 0
sl = append(sl, 1) // [1]
扩容
Slice依托数组实现,底层数组容量不足时可自动重新分配。追加数据通过append(返回值一定要再赋值给原slice);容量不足时会自动扩容:
- <1024时,扩大为原来2倍;
- >=1024时,扩大为原来的1.25倍;
var s []int // s == nilfmt.Println(s) // []fmt.Println(len(s)) // 0for i := 0; i < 5; i++ {s = append(s, i+1)}// 容量:0,1,2,4,8
插入元素
尾部插入
在插入元素时,若空间不足则会自动重新分配新的空间:
a = append(a, 1, 2, 3)
a = append(a, []int{1,2,3}...) // 追加切片时,需要使用...解包
头部插入
头部插入时,会引起内存的分配与复制操作:
// 即使一个元素,也要以切片的形式插入
a = append([]int{1}, a...)
a = append([]int{1,2,3}, a...)
中间插入
在中间(i)插入元素:
- 先通过append增长空间;
- 使用copy移动后面元素;
- 插入元素到指定位置
a = append(a, x...) // 先扩展出足够的空间
copy(a[i+len(x):], a[i:]) // 后移len(x)个元素,空出空间
copy(a[i:], x)
删除元素
从切片中删除的元素若是指针(特别是尾部删除时,可能还会被底层数组引用中,从而无法被gc回收);为了能及时的释放,在需要在删除前,先把对应元素设置为nil再删除;
a[len(a)-1]=nil
a = a[:len(a)-1]
尾部删除
删除尾部N个元素:
a = a[:len(a)-N]
头部删除
删除头部元素有两种方式:
- 改变数据指针(直接通过切片操作即可)
- 不改变数据指针(移动元素)
// 删除头部N个元素,改变数据指针
a = a[N:]// 删除切片头部元素,不改变数据指针:
a = append(a[:0], a[N:]...) // 在头部追加剩余元素
a = a[:copy(a, a[N:])] // 复制元素都头部,然后修改切片长度
中间删除
删除切片中间部分元素:
// 方法1:append追加,覆盖被删除元素
a = append(a[:i], a[i+N:]...)// 方法2:复制,覆盖被删除元素
a = a[:i+copy(a[i:], a[i+N:])]
遍历时删除
要在遍历时删除,就不能用range迭代的方式:
func removeAllLessEle(queueMax []int, ele int) []int {// pop all ele less than elefor j := 0; j < len(queueMax); {if queueMax[j] < ele {queueMax = append(queueMax[:j], queueMax[j+1:]...)} else{j = j + 1}}return queueMax
}
golang切片简介相关推荐
- GIS讲堂第二课-地图切片简介以及OL中的调用
概述: 在大家的支持与帮助下,"GIS讲堂"第二课已落下帷幕,在此对大家的支持与帮助表示衷心的感谢,同时呢,也给大家致歉,由于感冒的缘故,讲课的时候的各种毛病还请大家多多包涵,下面 ...
- golang切片转为字符串,字符串转切片
golang切片转为字符串,字符串转切片 package mainimport ("fmt""strings" )func main() {s := []str ...
- Golang(1)Golang语言简介
Golang(1)Golang语言简介 Golang(2)win10下安装Go语言 Golang(3)CentOS7系统安装Go语言 一.Golang的学习方向 (1)区块链研发工程师 (2)Go服务 ...
- golang bytes包 []byte 字节切片 简介
// 转换// 将 s 中的所有字符修改为大写(小写.标题)格式返回. func ToUpper(s []byte) []byte func ToLower(s []byte) []byte func ...
- golang 切片 截取参数 简介
以 s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}为例 建议:做slice截取时建议用两个参数,尤其是从底层数组进行切片操作时,因为这样在进行第一次append操作时 ...
- golang切片与for循环简介
切片 go语言中区间索引时使用左闭右开形式,即区间包括第一个元素但不包括最后一个元素 (译注:比如a = [1, 2, 3, 4, 5], a[0:3] = [1, 2, 3],不包含最后一个元素) ...
- golang 切片 接口_Go编程模式:切片,接口,时间和性能
在本篇文章中,我会对 Go 语言编程模式的一些基本技术和要点,这样可以让你更容易掌握 Go 语言编程.其中,主要包括,数组切片的一些小坑,还有接口编程,以及时间和程序运行性能相关的话题. 本文是全系列 ...
- Golang(1)-简介及特性
文章目录 一.Golang简介 1.1.什么是Golang 1.2.使用Golang完成的著名项目 1.3.Golang的特性 二.Golang的特性概述 2.1.自动垃圾回收 2.2.丰富的内置类型 ...
- Golang:简介、基本语法、函数、defer、Test功能
春招找实习告一段落了,好长时间没更CSDN的博客,期间写的一些笔记用 typora + git 直接推到github里面了,就没在CSDN里再发了,我的github:https://github.co ...
最新文章
- docker注册表回传失败 群晖6.2_Glances实时监视群晖运行状况
- python上海培训哪里比较好-python培训机构上海哪里好?
- 画图软件怎么做性能测试,软件性能测试能力提升解决方案.pdf
- 问题解决:pip无法使用,经升级后可以使用
- 王思聪花了100万的组装的电脑,网速到底有多快?
- vue项目打包部署到Tomcat上,一刷新就报错404
- 零基础自学SQL课程 | UNION 联合查询
- 通过监听手势滑动解决DrawerLayout只能边缘打开抽屉问题
- 随心所遇,随遇而安。
- (转)War3 地图编辑器脚本接口说明
- 解决linux系统Error starting userland proxy: listen tcp 0.0.0.0:xxx端口: bind: address already in use端口占用问题
- rhce8的rh294练习环境
- 小米note2不上Android9吗,我的第二部小米手机,小米9简单到不能再简单的简单体会...
- 某银行存储瘫痪、缺失6个小时数据,只能人工补录
- 异常处理 ?处理(try-catch) :甩锅(throws)_ java异常(Exception)处理
- 对于机器学习中数据拟合度和模型复杂度的一些建议
- 郑豪8.31月K收官提防大洗盘,日K箱体先高空,黄金亚欧盘最新操作建议
- python turtle 乌龟赛跑_Python编程 | 海龟绘图:Turtle Race 海龟赛跑游戏
- 电工电子产品做高低温试验的目的
- 热点账户冲扣设计方案