Golang 之数组、切片

Array类型

数组在使用前必须声明长度,在golang中,数组属于值类型,在函数传递中,实际传递的是数组的拷贝并不是数组指针拷贝 

Slice类型

是一种引用类型,它是不定长的,指向底层数组

Slice底层结构

type SliceHeader struct {
    Data uintptr #指向底层数组
    Len  int
    Cap  int
}

Slice 中len代表元素的个数,cap代表容量,在对slice进行append操作时,会导致slice的自动扩容。

切片扩容规则

1. 如果切片的容量小于1024个元素,那么扩容的时候slice的cap就翻番,乘以2;一旦元素个数超过1024个元素,增长因子就变成1.25,即每次增加原来容量的四分之一。

2. 如果扩容之后,还没有触及原数组的容量(系统分配的内存不够了),那么,切片中的指针指向的位置,就还是原数组,如果扩容之后,超过了原数组的容量,那么,Go就会开辟一块新的内存,把原来的值拷贝过来,这种情况丝毫不会影响到原数组。

nil切片和空切片的理解

func main() {
     var s1 []int
     s2 := make([]int,0)
     s4 := make([]int,0)

     fmt.Printf("s1 pointer:%+v, s2 pointer:%+v, s4 pointer:%+v, 
", *(*reflect.SliceHeader)(unsafe.Pointer(&s1)),*(*reflect.SliceHeader)(unsafe.Pointer(&s2)),*(*reflect.SliceHeader)(unsafe.Pointer(&s4)))
     fmt.Printf("%v
", (*(*reflect.SliceHeader)(unsafe.Pointer(&s1))).Data==(*(*reflect.SliceHeader)(unsafe.Pointer(&s2))).Data)
     fmt.Printf("%v
", (*(*reflect.SliceHeader)(unsafe.Pointer(&s2))).Data==(*(*reflect.SliceHeader)(unsafe.Pointer(&s4))).Data)
}
#输出
s1 pointer:{Data:0 Len:0 Cap:0}, s2 pointer:{Data:824634207952 Len:0 Cap:0}, s4 pointer:{Data:824634207952 Len:0 Cap:0}, 
false //nil切片和空切片指向的数组地址不一样
true  //两个空切片指向的数组地址是一样的,都是824634207952

nil切片和空切片指向的地址不一样。nil空切片引用数组指针地址为0(无指向任何实际地址)

空切片的引用数组指针地址是有的,且固定为一个值

原文地址:https://www.cnblogs.com/peterleee/p/14172095.html