golang切片
切片与数组
go的数组是这样的
array := [3]int{1,2,3}
array := [...]int{1,2,3}
go的切片
array := []int{1,2,3} //1
array := make([]int,2) //2
arr := [5]int{1,2,3,4,5}
array :=arr[1:3] //底层数组可见 会修改原数组
len和cap的区别
make切片有两个参数len和cap
len:代表底层数组可访问的范围 用索引访问不可越过这个界限
cap:代表底层数组的长度,如果append元素时没有超过这个cap,则不再创建底层数组,否则开辟新的空间,同时增大cap(这里有一个增大规则),所以如果适当设置大一些的cap还是能减少开销的
array := make([]int,2,5) //len=2 cap=5
array := make([]int,2) //make([]int,2,2)
arr = [9]int{1,2,3,4,5,6,7,8,9}
arr2 :=arr[2:5:6] //长度为 5-2 容量为6-2
切片传参
func Args(arr ...int){
}
Args(1,2,3,4,5)
这里arr的类型就是切片类型
切片的底层结构
runtime/slice.go
type slice struct {
array unsafe.Pointer
len int
cap int
}
unsafe.Pointer其实就是*int类型 指向内存地址
切片为什么是引用类型?
切片传入函数,同样也是值传递,会copy一份切片的值传入函数内,哪为什么又说是引用类型呢?为什么函数内部改变会影响原切片呢?
根据上面的切片底层结构我们知道,切片有一个指向底层数组的指针,虽然切片是传值复制了一份,同时指向底层数组的指针也复制了一份,但指针始终是指向同一个地址的,那么我们改变切片的值其实就是改变底层数组的值。因为他们还是共享底层地址的。
遍历切片的优化
我们知道,切片可以用range遍历
//耗时 因为要建立新的变量
for _,v:=range arrStr{
log.Println("执行操作:",v)
}
下面做一些优化,忽略值,而是用索引来,这样就不用再开辟空间创建一个变量并且赋值给变量了
//优化
arrStr:=[]string{"a","b","c","d"}
for key:=range arrStr{
log.Println("[优化]执行操作:",arrStr[key])
}
空切片的判断
空切片可以判断它的长度是否为0,但是判断为nil来判断这个切片是否为空是不准确的,
比如下面两种情况就要用len是否为0来判断:
empty1:=make([]int,0)
log.Println(empty1==nil) //false
empty1=[]int{}
log.Println(empty1==nil)
下面的就是为nil 因为这只是声明,而没有开辟地址
var empty2 []int
log.Println(empty2==nil) //true
切片的克隆
刚学习go切片的新手可能会进行最简单的操作
a := []int{1, 2, 3}
b := make([]int, len(a)) //使用copy函数必须复制切片的结构必须和源数据结构一致
copy(b, a)
上面的操作进行了很多不必要的工作,开辟空间等等...让代码看起来不是很简洁,内存也有一定开销,当然这里影响很小,再看如下的clone
arrStr:=[]string{"a","b","c","d"}
arrStrClone:=append(arrStr[:0:0],arrStr...)
这个操作笔者以前也没见过,但是看了大佬的书籍才学会的这种骚操作,代码很简洁
删除切片的元素
删除一段切片,如下,删除了 [1-3) 的元素,删除后为[a,d,e,f] 注意是前闭后开的
arrStrClone=[]string{"a","b","c","d","e","f"}
arrStrClone = append(arrStrClone[:1], arrStrClone[3:]...)
删除一个元素
其实是删除一段元素的特例,这里就不举例了
切片的插入
如何在切片中插入切片呢?或者在切片中插入元素呢?
其实和删除的思想是一样的
// Push(插入到结尾)
s = append(s, elements...)
// Unshift(插入到开头)
s = append(elements, s...)
//将切片elements的元素插入到s切片的i位置之后
s = append(s[:i], append(elements, s[i:]...)...)
切片实现栈队列
出
s, e = s[1:], s[0] //shift操作 将开头元素弹出
s, e = s[:len(s)-1], s[len(s)-1] //pop 将尾元素弹出
入
// Push(插入到结尾)
s = append(s, elements...)
// Unshift(插入到开头)
s = append(elements, s...)
关于并发
注意,go里面的特殊容器都是现成不安全的,多个并发读取可以,但是并发修改是不允许的
golang切片的更多相关文章
- golang切片和数组的区别
好久的没有写博客了,这段时间没事研究了下go这门语言. 我们先介绍下go中的数组和切片的区别和用法 说了这么多 我们先来看段代码吧 var arr1 [3]int var arr2 [3]int = ...
- golang切片slice
切片slice是引用类型 len()函数获取元素的个数 cap()获取数组的容量 1.申明方式 (1)var a []int 与数组不同的是他不申明长度(2)s2 := make([]int, 3, ...
- golang切片数据结构解释
1. 切片:切片是数组的一个引用,因此切片是引用类型 func main() { var arr = [6]int{1, 2, 3, 4, 5} var slice = arr[1:] fmt.Pri ...
- Golang切片的三种简单使用方式及区别
概念 切片(slice)是建立在数组之上的更方便,更灵活,更强大的数据结构.切片并不存储任何元素而只是对现有数组的引用. 三种方式及细节案例 ①定义一个切片,然后让切片去引用一个已经创建好的数组 pa ...
- golang切片类型
切片slice 其本身并不是数组,它指向底层的数组 作为变长数组的替代方案,可以关联底层数组的局部或全部 为引用类型 可以直接创建或从底层数组获取生成 使用len()获取元素个数,cap()获取容量 ...
- golang 切片和数组在for...range中的区别
切片是引用类型,而数组是值类型,并且for...range有以下规则: range表达式只会在for语句开始执行时被求值一次,无论后边会有多少次迭代 range表达式的求值结果会被复制,也就是说,被迭 ...
- golang 切片小记
1 切片初始化 func printSlice(s []int) { fmt.Printf("len=%d cap=%d underlying array:%p, %v\n", l ...
- golang 切片和map查询比较
package main import ( "fmt" "time" ) var testTimeSlice = []string{"aa" ...
- golang 切片扩容, 时间复杂度
在切片扩容时,如果原来的底层数组足够大,能放的下 append 的数据,就不会新建底层数组.而如果不够的话,则会分配一个新的数组.也因此是 O(n) 的时间复杂度
随机推荐
- 05 - Tomcat 线程池的配置与优化
添加 Executor 在server.xml中的Service节点里面,增加executor节点,然后配置connector的executor属性,如下: <Executor name=&qu ...
- L3-016 二叉搜索树的结构 (30 分)
二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值:若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值:它的左.右子树也分别 ...
- python开发常见应用第一卷(OS遍历文件并存储文件路径到数据库)
之前我们爬取完指定网站的图片后,会将它门保存到服务器或本地的数据库中,真正的工作中大多数是采用分布式的方式来爬取的,所以这些图片会分布在很多的主机上面,当被引用时需要根据IP+图片路径来引用并且加载, ...
- MySQL的详细操作
MySQL的详细操作 存储引擎 不同的数据应该有不同的处理机制 mysql存储引擎 Innodb:默认的存储引擎 查询速度较myisam慢 但是更安全,支持事务,行锁,外键由于以上的支持,数据更安全, ...
- iOS动画效果集合、 通过摄像头获取心率、仿淘宝滑动样式、瀑布流、分类切换布局等源码
iOS精选源码 动画知识运用及常见动画效果收集 较为美观的多级展开列表 MUImageCache -简单轻量的图片缓存方案 iOS 瀑布流之栅格布局 一用就上瘾的JXCategoryView iOS ...
- 吴裕雄--天生自然 R语言开发学习:基础知识
1.基础数据结构 1.1 向量 # 创建向量a a <- c(1,2,3) print(a) 1.2 矩阵 #创建矩阵 mymat <- matrix(c(1:10), nrow=2, n ...
- 信贷建模little tricks
一.逻辑回归 概率分类模型 选取样本:对逻辑回归这种概率分类模型来说维持原来样本真实的分布还是有必要的,但是对一些树模型来说可以通过采样来平衡样本. 原来评分卡建模还有个拒绝推断,就是为了还原人群真实 ...
- C++ 中类的内存布局
在许多笔试面试中都会涉及到sizeof 运算符的求值问题. 这类问题主要分四类: 基本数据类型,如int,bool,fload,long,long,int * 等,这一类比较简单,但要注意x86和x6 ...
- Jumpserver 一键部署(支持离线安装)
1.教程介绍1.1::通过本教程起到抛砖引玉效果,希望各位喜爱Jumpserver堡垒机的朋友受益良多. 1.2::以下提供的任何软件仅供学习交流使用. 2.下载链接2.1::centos_1810最 ...
- deepin 更改默认网卡名称为eth和wlan
deepin 更改默认的网卡名称为eth和无线网卡名wlan vim /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT="sqlash quiet ...