码迷,mamicode.com
首页 > 其他好文 > 详细

[go]slice

时间:2020-01-11 00:34:38      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:print   形参   alt   包含   src   png   32bit   ken   系统   

切片的结构

切片是一个结构体

type slice struct {
    array unsafe.Pointer //指向底层数组
    len   int
    cap   int
}

技术图片

占用内存大小: 在64bit系统上占24个字节.

//word大小
32bit: 1word=4byte
64bit: 1word=8byte

//在64bit系统上slice占24个字节
type slice struct {
    array unsafe.Pointer //8byte
    len   int            //8byte
    cap   int            //8byte
}

fmt.Println(unsafe.Sizeof([]int{})) //24bytes

切片数据包含在与切片关联的底层数组里, 拷贝切片时, 不会涉及底层数组数组的拷贝, 仅拷贝24bytes

技术图片

定义

字面量方式

// 字面量方式定义

var arr[]int       //nil切片: 指向nil

arr:= []int{}      //空切片,  有内存地址分配
arr:=make([]int,0)

println(a==nil,b==nil) //只能和nil比较, slice引用类型之间不支持==运算

b:= []int{1,2,5:10}

技术图片

技术图片

make方式

// make方式:

make([]T, len, cap)  //len参数必须, cap参数可选, 默认cap==size

len: 用于限定可读写的元素数量.
cap: 表示切片所引用数组片段的真实长度.

arr:=make([]int, 3, 5)

技术图片

arr := make([]int,3)
fmt.Println(len(arr), cap(arr)) //3 3

arr := make([]int, 3, 4)
fmt.Printf("%#v",arr) //[]int{0, 0, 0}
  • len和cap的说明
//len: 用于限定可读写的元素数量. 

arr := make([]int, 2, 3)
arr[0] = 0
arr[1] = 1
arr[2] = 2 // index out of range [2] with length 2

如果要扩容slice, 使用append函数(making slice a dynamic data structure). 当append时:

  • 如果cap够, append使用原数组

技术图片

  • 如果cap不够, append会新开辟一个backend array内存空间. 并重置cap. 当cap<1000时, 成倍的增长cap; 当cap>1000,增长因子为1.25.

技术图片

从数组/切片reslice

// 从数组/切片获取
    arr = [i,j,k]
    len = j-i
    cap = k-i

// 一个例子
 x:= [...]int{0,1,2,3,4,5,6,7,8,9} 
  
 操作        得到的切片                 len   cap   备注 
-------------+--------------------------+----+------+------------------------------ 
 x[:]         [0 1 2 3 4 5 6 7 8 9]     10   10   x[0:len(x)] 
 x[2:5]       [2 3 4]                   3    8
 x[2:5:7]     [2 3 4]                   3    5
 x[4:]        [4 5 6 7 8 9]             6    6    x[4:len(x)] 
 x[:4]        [0 1 2 3]                 4    10   x[0:4] 
 x[:4:6]      [0 1 2 3]                 4    6    x[0:4:6]
  • 使用 arr = [i,j], 注 这里的默认cap,是原始arr的长度-i
    技术图片

  • 使用arr = [i,j,k]
    技术图片

  • 使用arr = [i,j,k], 设置j=k, 即len=cap的好处: 修改切片内容时, 避免影响其他切片.
    技术图片

slice是引用类型

  • slice只能和nil比较

  • slice的赋值

切片是一个结构体, 切片在64bit系统下占用24bytes. 与切片关联的数据存放在底层数组里,不属于切片本身.
所以将切片赋值到任意变量时, 对底层数组的大小都不会有影响, 赋值时只会复制切片本身, 不会涉及底层数组里数据.

技术图片

  • slice函数参数传递

Go 语言的函数参数传递,只有值传递,没有引用传递。
函数形参是一个局部变量, 调用函数时, 会将变量拷贝一份, 赋值给函数形参.
这里slice的拷贝, 仅仅是拷贝slice的结构体, 不会涉及与slice关联的底层数组的数据.

// 函数foo接收一个整型切片,并返回这个切片
func foo(slice []int) []int {
  ...
  return slice
}

func main(){
    // 分配包含100万个整型值的切片
    slice := make([]int, 1e6)

    // 将slice传递到函数foo
    slice = foo(slice)
}

技术图片

[go]slice

标签:print   形参   alt   包含   src   png   32bit   ken   系统   

原文地址:https://www.cnblogs.com/iiiiiher/p/12178432.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!