对于切片的一些理解

切片

基本的结构

type struct {
    Data uintptr
    Len int
    Cap int
}

一个切片是由数据指针加上长度和容量组成的,类似与C++中的vector。

常见的初始化操作

var (
    a []int					// 等价于nil
    b = []int{}				// 表示一个空的切片,不等于nil
    c = []int{1,2,3}		// len,cap都为3的切片
    d = c[:2]				// cap为3,len为2。与c共享一片内存地址
    e = c[0:2:cap(c)]		// cap为3,len为2。与c共享一片内存地址
    f = c[:0]				// cap为3,len为0。
    g = make([]int,3)		// cap为3,len为3。里面的参数都是nil
    h = make([]int,2,3)		// cap为3,len为2。里面参数前两个是nil
)

对于切片的操作

添加

一般使用append方法对于切片进行元素添加。

a = append(a,0)
a = append(0,a)

第二行是在开头插入元素,一般会导致内存的重新分配,从而性能比较差。

可以利用copy方法和append方法进行组合,实现一些功能。

a = append(a,0)
copy(a[i+1:0],a[i:])	// a[i:]向后移动一个位置
a[i] = x

copy可以避免多个切片拷贝的时候共享一片内存时进行修改导致的bug。

扩容

在对于切片进行添加的时候,会自动触发切片的扩容的操作。

对于具体的扩容策略,最基本的是当cap小于1024时,每次翻倍。大于1024时每次变为原来的1.25倍。

但是这个策略只适用于每次增加一个元素的情况,如果一次增加多个元素的时候,就不一定是这个扩容策略了。

如果当前cap为4,len为3,一次append6个元素。那么这个时候,append操作之后的cap就是9。

并且具体的slice的类型对于cap也有关系。

package main

import "fmt"

func main() {
	a := []byte{1, 0}
	a = append(a, 1, 1, 1)
	fmt.Println("cap of a is ", cap(a))

	b := []int{23, 51}
	b = append(b, 4, 5, 6)
	fmt.Println("cap of b is ", cap(b))

	c := []int32{1, 23}
	c = append(c, 2, 5, 6)
	fmt.Println("cap of c is ", cap(c))

	type D struct {
		age  byte
		name string
	}
	d := []D{
		{1, "123"},
		{2, "234"},
	}

	d = append(d, D{4, "456"}, D{5, "567"}, D{6, "678"})
	fmt.Println("cap of d is ", cap(d))
}
cap of a is  8
cap of b is  6
cap of c is  8
cap of d is  5

这里面的基本原理涉及到go的内存管理操作,不是很懂。

https://blog.csdn.net/weixin_34100227/article/details/91373911

删除

a = []int{1,2,3}
a = a[:len(a) - N]	// 删除尾部N个元素
a = a[N:]			// 删除头部N个元素
a = a[:i+copy(a[i:],a[i+N:])]	// 删除中间的N个元素

使用技巧

可能的内存泄漏

因为Go的GC机制,只要存在内存引用,整片内存都不会被释放掉。可能会降低整体的系统性能。最好是只把感兴趣的数据单独寸一个切片。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值