• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Go切片操作

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

go语言中的切片,可以看作是可变化长度的数组(动态数组)。有长度(len)和容量(cap),容量必大于等于长度。

切片的结构体定义如下:

type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}

 

切片的定义方式

var (
    a []int               // nil切片, 和 nil 相等, 一般用来表示一个不存在的切片
    b = []int{}           // 空切片, 和 nil 不相等, 一般用来表示一个空的集合
    c = []int{1, 2, 3}    // 有3个元素的切片, len和cap都为3
    d = c[:2]             // 有2个元素的切片, len为2, cap为3
    e = c[0:2:cap(c)]     // 有2个元素的切片, len为2, cap为3
    f = c[:0]             // 有0个元素的切片, len为0, cap为3
    g = make([]int, 3)    // 有3个元素的切片, len和cap都为3
    h = make([]int, 2, 3) // 有2个元素的切片, len为2, cap为3
    i = make([]int, 0, 3) // 有0个元素的切片, len为0, cap为3
)

 

遍历

    for i := range a {
        fmt.Printf("a[%d]: %d\n", i, a[i])
    }
    for i, v := range b {
        fmt.Printf("b[%d]: %d\n", i, v)
    }
    for i := 0; i < len(c); i++ {
        fmt.Printf("c[%d]: %d\n", i, c[i])
    }

 

添加元素

1.开头添加(一般都会重新分配内存)

var a = []int{1,2,3}
a = append([]int{0}, a...)        // 在开头添加1个元素
a = append([]int{-3,-2,-1}, a...) // 在开头添加1个切片

 

2.末尾添加(注意:容量不足,append会重新分配内存)

var a []int
a = append(a, 1)               // 追加1个元素
a = append(a, 1, 2, 3)         // 追加多个元素, 手写解包方式
a = append(a, []int{1,2,3}...) // 追加一个切片, 切片需要解包

 

3.中间添加(append和copy组合实现)

// append实现,第二个append调用会创建一个临时的切片
var a []int
a = append(a[:i], append([]int{x}, a[i:]...)...)     // 在第i个位置插入x
a = append(a[:i], append([]int{1,2,3}, a[i:]...)...) // 在第i个位置插入切片

// append和copy组合实现,避免创建中间的临时切片
a = append(a, 0) // 先扩容
copy(a[i+1:], a[i:]) // a[i:]向后移动1个位置
a[i] = x             // 设置新添加的元素

// append和copy组合,在指定位置插入切片(多个元素)
a = append(a, x...) // 没有专门的函数来扩容,只有使用append
copy(a[i+len(x):], a[i:])
copy(a[i:], x)

 

删除元素

1.删除元素

a := []int{1, 2, 3}

// 移动数据指针
a = a[1:] // 删除开头1个元素
a = a[N:] // 删除开头N个元素

// 可以用append原地完成(所谓原地完成是指在原有的切片数据对应的内存区间内完成,不会导致内存空间结构的变化)
a = append(a[:0], a[1:]...) // 删除开头1个元素
a = append(a[:0], a[N:]...) // 删除开头N个元素

// 用copy完成删除开头的元素
a = a[:copy(a, a[1:])] // 删除开头1个元素
a = a[:copy(a, a[N:])] // 删除开头N个元素

 

2.删除尾部(最快)

a = a[:len(a)-1]   // 删除尾部1个元素
a = a[:len(a)-N]   // 删除尾部N个元素

 

3.删除中间部分

// 使用append
a = append(a[:i], a[i+1:]...) // 删除中间1个元素
a = append(a[:i], a[i+N:]...) // 删除中间N个元素

// 使用copy
a = a[:i+copy(a[i:], a[i+1:])]  // 删除中间1个元素
a = a[:i+copy(a[i:], a[i+N:])]  // 删除中间N个元素

 

总结

切片高效操作的要点是要降低内存分配的次数,尽量保证append操作不会超出cap的容量,降低触发内存分配的次数和每次分配内存大小。

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Go语言学习笔记(四)结构体struct&amp;接口Interface&amp;反射reflect ...发布时间:2022-07-10
下一篇:
Go代码风格和规范发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap