golang切片内存应用技巧详解
在Go语言中切片是使用非常频繁的一种聚合类型,它代表变长的序列,底层引用一个数组对象。一个切片由三个部分构成:指针、长度和容量。指针指向该切片自己第一个元素对应的底层数组元素的内存地址。
切片的类型声明如下:
typeslicestruct{ arrayunsafe.Pointer lenint capint }
多个切片之间可以共享底层数组的数据,并且引用的数组区间可能重叠。利用切片的这个特性我们可以在原有内存空间中对切片进行反转、筛选和去重等操作,这样就不用声明一个指向新内存的切片来存储结果,从而节省了内存空间以及扩展底层数组的消耗,这在切片长度足够大时效果就会非常显著。
下面这些例子都是在切片底层数组的内存空间上进行的操作,需要注意的是这些操作在底层数组上生成新切片的同时也会更改底层数组。
删除指定位置的元素
下面的函数从原切片中删除索引位置i上的元素
funcremove(slice[]int,iint)[]int{ copy(slice[i:],slice[i+1:]) returnslice[:len(slice)-1] } funcmain(){ s:=[]int{5,6,7,8,9} fmt.Println(remove(s,2))//"[5689]" }
内置的copy函数可以方便地将一个切片复制另一个相同类型的切片上。
筛选元素
下面的函数从输入的源切片中筛选出满足条件的切片元素,返回一个满足条件的元素组成的新切片。
typefuncTypefunc(T)bool//代表筛选逻辑函数,可以按需实现 funcfilter(a[]T,ffuncType)[]T{ b:=a[:0] for_,x:=rangea{ iff(x){ b=append(b,x) } } returnb }
反转切片
funcreverse(a[]T)[]T{ fori:=len(a)/2-1;i>=0;i--{ opp:=len(a)-1-i a[i],a[opp]=a[opp],a[i] } returna }
分组切片
下面的函数接收一个[]int类型的源切片actions,返回一个按指定长度分组的嵌套切片(解释起来好难,用过PHP的同学可以理解为Go版本的array_chunk函数,没用过的看下面例子)。假设切面值为:[]int{0,1,2,3,4,5,6,7,8,9},设置分组中元素长度batchSize为3,函数调用后返回的分组后的切片为[[012][345][678][9]]
funcchunk(actions[]int,batchSizeint)[]int{ varbatches[][]int forbatchSize这里顺便说一下,完整的切片表达式形式如下:
input[low:high:max]最后一个max的作用是,生成的切片的cap(容量)为max-low。
原地去重(只针对可比较的切片类型)
import"sort" funcmain(){ in:=[]int{3,2,1,4,3,2,1,4,1}//anyitemcanbesorted sort.Ints(in) j:=0 fori:=1;i文章中部分例子来自golang官方的GitHub的wiki,在这个wiki里介绍了很多的切片使用技巧,了解更多可以访问golang的GitHubWikihttps://github.com/golang/go/wiki/SliceTricks#filtering-without-allocating
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。