您的位置 首页 golang

Golang slice注意啦

日常开发中slice经常用,就是对于一个老司机来说有时也容易忽略。一起看下:

//Slice 数据结构

type Slice struct {

ptr unsafe.Pointer // Array pointer

len int // slice length

cap int // slice capacity

}

//使用make创建

make([]T, length, capacity)

len()取数组长度,在内存中进行了初始化实际存在的元素的个数

cap()取数组容量,最大可存放元素个数(每次cap改变的时候指向array内存的指针都在变化)

注意:slice的容量,如果通过make函数创建slice的时候指定了容量参数,那内存管理器会根据指定的容量的值先划分一块儿内存空间,然后才在其中按长度,存放数组元素,多余的部分处于空闲状态。

在slice上追加元素的时候,首先会到这块儿空闲的内存中,如果添加的元素的个数超过了容量的值,内存管理器会重新划分一块容量值为原容量2倍大小的内存空间,这个机制可以提升运算性能,因为内存的频繁重新划分会降低性能。

实际go在append的时候放大cap是有规律的。在 cap 小于1024的情况下是每次扩大到 2 * cap ,当大于1024之后就每次扩大到 1.25 * cap 。

在实际使用中,我们最好事先预期好一个cap,这样在使用append的时候可以避免反复重新分配内存复制之前的数据,减少不必要的性能消耗。

示例:

package main

import “fmt”

func main() {

/* 创建切片 */

numbers := []int{0,1,2,3,4,5,6,7,8}

printSlice(numbers)

/* 打印原始切片 */

fmt.Println(“numbers ==”, numbers)

/* 打印子切片从 索引 1(包含) 到索引4(不包含)*/

fmt.Println(“numbers[1:4] ==”, numbers[1:4])

/* 默认下限为 0*/

fmt.Println(“numbers[:3] ==”, numbers[:3])

/* 默认上限为 len(s)*/

fmt.Println(“numbers[4:] ==”, numbers[4:])

numbers1 := make([]int,0,5)

printSlice(numbers1)

/* 打印子切片从索引 0(包含) 到索引 2(不包含) */

number2 := numbers[:2]

printSlice(number2)

/* 打印子切片从索引 2(包含) 到索引 5(不包含) */

number3 := numbers[4:5]

printSlice(number3)

number3 = append(number3, 4,5,6,7,8)

printSlice(number3)

}

func printSlice(x []int){

fmt.Printf(“len=%d cap=%d slice=%v\n”,len(x),cap(x),x)

}

执行以上代码输出结果为:

len=9 cap=9 slice=[0 1 2 3 4 5 6 7 8]

numbers == [0 1 2 3 4 5 6 7 8]

numbers[1:4] == [1 2 3]

numbers[:3] == [0 1 2]

numbers[4:] == [4 5 6 7 8]

len=0 cap=5 slice=[]

len=2 cap=9 slice=[0 1]

len=3 cap=5 slice=[4] //此时指针已经到index 2 处,所以cap容量为9-2=7

len=6 cap=10 slice=[5 6 4 5 6 7 8] //此时cap已经扩容为2倍

更多内容请关注每日编程,每天进步一点。

文章来源:智云一二三科技

文章标题:Golang slice注意啦

文章地址:https://www.zhihuclub.com/98855.shtml

关于作者: 智云科技

热门文章

网站地图