zoukankan      html  css  js  c++  java
  • 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(无指向任何实际地址)

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

  • 相关阅读:
    Zend Framework入门指引
    [技巧]枚举子集的飘逸写法
    [120120]fzyz机房聚会
    [解题报告]ural 1041 Nikifor
    [转载]二分图匹配总结
    [存档]xx09210xxx2010ACMICPC竞赛总结
    [解题报告]ural 1163 Chapaev
    [总结]勿忘本心
    [解题报告]ural 1176 Hyperchannels
    [存档]xx09210xxx2011ACMICPC竞赛总结
  • 原文地址:https://www.cnblogs.com/peterleee/p/14172095.html
Copyright © 2011-2022 走看看