zoukankan      html  css  js  c++  java
  • Go语言中底层数组和切片的关系以及数组扩容规则

    Go语言中底层数组和切片的关系以及数组扩容规则

    demo

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	// 声明一个底层数组,长度为10,容量为10
    	arr := []int {0,1,2,3,4,5,6,7,8,9}
    	fmt.Printf("[%T]len(arr)=%d,cap(arr)=%d 
    ",arr,len(arr),cap(arr))
    	// 声明两个切片,分别取底层数组的[1,4],[7:]
    	s1 := arr[1:4]
    	fmt.Printf("[%T]len(s1)=%d,cap(s1)=%d 
    ",s1,len(s1),cap(s1))
    	s2 := arr[7:]
    	fmt.Printf("[%T]len(s2)=%d,cap(s2)=%d 
    ",s2,len(s2),cap(s2))
    	// 数组越界指的是超出数组长度,例如下面报:panic: runtime error: index out of range [3] with length 3
    	//fmt.Println(s1[3])
    	// s1可以添加元素,添加后s1长度变大,容量不变,同时底层数组被修改
    	s1 = append(s1, 20)
    	fmt.Printf("[%T]len(s1)=%d,cap(s1)=%d 
    ",s1,len(s1),cap(s1))
    	fmt.Println(arr)
    	// s2如果需要添加元素,因为容量不够,需要进行扩容,开辟新数组,将原来的7,8,9拷贝过来,再添加一个20,长度为4,容量为6
    	s2 = append(s2,20)
    	fmt.Printf("[%T]len(s2)=%d,cap(s2)=%d 
    ",s2,len(s2),cap(s2))
    	// 此时修改s2的数组,底层数组arr不再受影响
    	s2[1] = 10
    	fmt.Println(arr)
    
    	// 容量为什么为6?涉及到数组的扩容规则,举个例子如下:
    	ints := []int{1,2} // 原容量oldCap =2
    	ints = append(ints,3,4,5) // 预估容量cap = 5
    	/*
    	 if oldCap * 2 < cap {
    		newCap = cap
    	} else {
    		if oldLen < 1024 {
    			newCap = oldCap *2
    		}else if oldLen >= 1024 {
    			newCap = oldCap *1.25
    		}
    	}
    	*/
    	// 上面例子中newCap = 5,int数组所占字节为5*8 = 40,但go语言向内存管理模块向操作系统申请的内存容量却没有40大小的,只有48符合,于是newCap = 48/8 = 6
    	// go语言内存管理模块是16bytes叠加的,8,16,32,48,64,80,96
    	// 参考博客:https://www.cnblogs.com/ldaniel/p/8502867.html?utm_source=debugrun&utm_medium=referral
    	fmt.Printf("[%T]len(ints)=%d,cap(ints)=%d 
    ",ints,len(ints),cap(ints))
    	// 例子验证第二种情况
    	ints2 := []int{1,2}
    	ints2 = append(ints2,3)
    	// 此时oldCap * 2 > cap ,满足第二种情况,newCap = 4
    	fmt.Printf("[%T]len(ints2)=%d,cap(ints2)=%d 
    ",ints2,len(ints2),cap(ints2))
    }
    
    

    打印输出参考

    [[]int]len(arr)=10,cap(arr)=10 
    [[]int]len(s1)=3,cap(s1)=9 
    [[]int]len(s2)=3,cap(s2)=3 
    [[]int]len(s1)=4,cap(s1)=9 
    [0 1 2 3 20 5 6 7 8 9]
    [[]int]len(s2)=4,cap(s2)=6 
    [0 1 2 3 20 5 6 7 8 9]
    [[]int]len(ints)=5,cap(ints)=6 
    [[]int]len(ints2)=3,cap(ints2)=4 
    
    Process finished with exit code 0
    
  • 相关阅读:
    Linux内核空间-用户空间通信之debugfs
    Mysql 启动失败 报错 1067
    [置顶] hdu3018解题报告--也是白话几笔画学习总结
    【Todo】蒙特卡洛(蒙特卡罗)树 & 卷积网络
    基本分类方法——KNN(K近邻)算法
    SVM(支持向量机)与统计机器学习 & 也说一下KNN算法
    可重入锁 & 自旋锁 & Java里的AtomicReference和CAS操作 & Linux mutex不可重入
    【Todo】Nginx架构学习
    【转载】C++异常机制的学习
    关于协程的学习 & 线程栈默认10M
  • 原文地址:https://www.cnblogs.com/Kingram/p/13630313.html
Copyright © 2011-2022 走看看