时间:2021-05-22
在 Go 语言中切片是使用非常频繁的一种聚合类型,它代表变长的序列,底层引用一个数组对象。一个切片由三个部分构成:指针、长度和容量。指针指向该切片自己第一个元素对应的底层数组元素的内存地址。
切片的类型声明如下:
type slice struct { array unsafe.Pointer len int cap int}多个切片之间可以共享底层数组的数据,并且引用的数组区间可能重叠。利用切片 的这个特性我们可以在原有内存空间中对切片进行反转、筛选和去重等操作,这样就不用声明一个指向新内存的切片来存储结果,从而节省了内存空间以及扩展底层数组的消耗,这在切片长度足够大时效果就会非常显著。
下面这些例子都是在切片底层数组的内存空间上进行的操作,需要注意的是这些操作在底层数组上生成新切片的同时也会更改底层数组。
删除指定位置的元素
下面的函数从原切片中删除索引位置i上的元素
func remove(slice []int, i int) []int { copy(slice[i:], slice[i+1:]) return slice[:len(slice)-1]}func main() { s := []int{5, 6, 7, 8, 9} fmt.Println(remove(s, 2)) // "[5 6 8 9]"}内置的copy函数可以方便地将一个切片复制另一个相同类型的切片上。
筛选元素
下面的函数从输入的源切片中筛选出满足条件的切片元素,返回一个满足条件的元素组成的新切片。
type funcType func(T) bool //代表筛选逻辑函数,可以按需实现func filter(a []T, f funcType) []T { b := a[:0] for _, x := range a { if f(x) { b = append(b, x) } } return b}反转切片
分组切片
下面的函数接收一个[]int 类型的源切片actions, 返回一个按指定长度分组的嵌套切片(解释起来好难,用过PHP 的同学可以理解为 Go 版本的array_chunk 函数,没用过的看下面例子)。假设切面值为:[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},设置分组中元素长度batchSize为3,函数调用后返回的分组后的切片为[[0 1 2] [3 4 5] [6 7 8] [9]]
func chunk(actions []int, batchSize int) []int { var batches [][]int for batchSize < len(actions) { actions, batches = actions[batchSize:], append(batches, actions[0:batchSize:batchSize]) } batches = append(batches, actions) return batches}func main() { actions := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} batchSize := 3 chunks = chunk(actions, batchSize) //chunks 为[[0 1 2] [3 4 5] [6 7 8] [9]]}这里顺便说一下,完整的切片表达式形式如下:
input[low:high:max]最后一个 max 的作用是,生成的切片的cap(容量)为max - low。
原地去重(只针对可比较的切片类型)
文章中部分例子来自golang 官方的 GitHub 的 wiki ,在这个 wiki 里介绍了很多的切片使用技巧,了解更多可以访问golang 的 GitHub Wiki https://github.com/golang/go/wiki/SliceTricks#filtering-without-allocating
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
golang复合类型包括:结构体、数组、切片、Maps。1、数组数组golang中的数组与C语言中的数组差异很大,倒更类似Pascal中的数组。(Slice,下
golang修改结构体中的切片值,直接传结构体地址就可以packagemainimport"fmt"typerspInfostruct{KeyWordsstri
详解Pythonlist与NumPy.ndarry切片之间的区别实例代码:#list切片返回的是不原数据,对新数据的修改不会影响原数据In[45]:list1=
问题描述:两个go程轮流打印一个切片。Golang实现:使用两个channel,只用来判断packagemainimport("fmt""sync")//两个g
golang语言协程协程中使用全局变量、局部变量、指针、map、切片等作为参数时需要注意,此变量的值变化问题。与for循环,搭配使用更需谨慎。1、内置函数时直接