目录

创建

创建与初始化

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切片简介相关推荐

  1. GIS讲堂第二课-地图切片简介以及OL中的调用

    概述: 在大家的支持与帮助下,"GIS讲堂"第二课已落下帷幕,在此对大家的支持与帮助表示衷心的感谢,同时呢,也给大家致歉,由于感冒的缘故,讲课的时候的各种毛病还请大家多多包涵,下面 ...

  2. golang切片转为字符串,字符串转切片

    golang切片转为字符串,字符串转切片 package mainimport ("fmt""strings" )func main() {s := []str ...

  3. Golang(1)Golang语言简介

    Golang(1)Golang语言简介 Golang(2)win10下安装Go语言 Golang(3)CentOS7系统安装Go语言 一.Golang的学习方向 (1)区块链研发工程师 (2)Go服务 ...

  4. golang bytes包 []byte 字节切片 简介

    // 转换// 将 s 中的所有字符修改为大写(小写.标题)格式返回. func ToUpper(s []byte) []byte func ToLower(s []byte) []byte func ...

  5. golang 切片 截取参数 简介

    以 s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}为例 建议:做slice截取时建议用两个参数,尤其是从底层数组进行切片操作时,因为这样在进行第一次append操作时 ...

  6. golang切片与for循环简介

    切片 go语言中区间索引时使用左闭右开形式,即区间包括第一个元素但不包括最后一个元素 (译注:比如a = [1, 2, 3, 4, 5], a[0:3] = [1, 2, 3],不包含最后一个元素) ...

  7. golang 切片 接口_Go编程模式:切片,接口,时间和性能

    在本篇文章中,我会对 Go 语言编程模式的一些基本技术和要点,这样可以让你更容易掌握 Go 语言编程.其中,主要包括,数组切片的一些小坑,还有接口编程,以及时间和程序运行性能相关的话题. 本文是全系列 ...

  8. Golang(1)-简介及特性

    文章目录 一.Golang简介 1.1.什么是Golang 1.2.使用Golang完成的著名项目 1.3.Golang的特性 二.Golang的特性概述 2.1.自动垃圾回收 2.2.丰富的内置类型 ...

  9. Golang:简介、基本语法、函数、defer、Test功能

    春招找实习告一段落了,好长时间没更CSDN的博客,期间写的一些笔记用 typora + git 直接推到github里面了,就没在CSDN里再发了,我的github:https://github.co ...

最新文章

  1. docker注册表回传失败 群晖6.2_Glances实时监视群晖运行状况
  2. python上海培训哪里比较好-python培训机构上海哪里好?
  3. 画图软件怎么做性能测试,软件性能测试能力提升解决方案.pdf
  4. 问题解决:pip无法使用,经升级后可以使用
  5. 王思聪花了100万的组装的电脑,网速到底有多快?
  6. vue项目打包部署到Tomcat上,一刷新就报错404
  7. 零基础自学SQL课程 | UNION 联合查询
  8. 通过监听手势滑动解决DrawerLayout只能边缘打开抽屉问题
  9. 随心所遇,随遇而安。
  10. (转)War3 地图编辑器脚本接口说明
  11. 解决linux系统Error starting userland proxy: listen tcp 0.0.0.0:xxx端口: bind: address already in use端口占用问题
  12. rhce8的rh294练习环境
  13. 小米note2不上Android9吗,我的第二部小米手机,小米9简单到不能再简单的简单体会...
  14. 某银行存储瘫痪、缺失6个小时数据,只能人工补录
  15. 异常处理 ?处理(try-catch) :甩锅(throws)_ java异常(Exception)处理
  16. 对于机器学习中数据拟合度和模型复杂度的一些建议
  17. 郑豪8.31月K收官提防大洗盘,日K箱体先高空,黄金亚欧盘最新操作建议
  18. python turtle 乌龟赛跑_Python编程 | 海龟绘图:Turtle Race 海龟赛跑游戏
  19. 电工电子产品做高低温试验的目的
  20. 热点账户冲扣设计方案

热门文章

  1. iOS VoIP PushKit 的问题
  2. Excel 2010 里怎么不显示空单元格中的数字0
  3. 丢手帕问题 java_初学java丢手帕问题
  4. 红米note7支持html,红米Note 7
  5. java简单搭建分布式架构
  6. 快速幂运算(入门完整版)
  7. 算法4 随书 IDE:DrJava 在 Win10 下高分屏字体太小问题解决
  8. 离婚率离婚率离婚率离婚率
  9. SQL中NVL和NVL2有什么区别,以及NULLIF 的使用
  10. vim 删除行首和行尾空格