美文网首页程序员
golang slice学习

golang slice学习

作者: Lucas_Ye | 来源:发表于2017-01-03 19:51 被阅读89次

    1. slice的结构

    type slice struct {
          index  *interface  //指向首元素的指针
          len    int         //长度
          cap    int         //容量
    }
    
    slice是类型

    slice类型声明后类似于:
    var arr slice 而非 var arr *slice
    append时,如果超过cap容量,会重新分配空间.
    新空间的指针会被保存在index中,slice本身的指针不变.
    举个栗子🌰:

    func F() {
       intArr := make([]int, 1)
       fmt.Println(&intArr[0], len(intArr), cap(intArr))
       defer f(intArr)
       intArr = append(intArr, 1)
       fmt.Println(&intArr[0], len(intArr), cap(intArr))
       return
    }
    
    func f(intArr []int) {
       fmt.Println(&intArr[0], len(intArr), cap(intArr))
    }
    
    //结果
    0xc42000d2d0 1 1
    0xc42000d300 2 2
    0xc42000d2d0 1 1
    
    • 在defer中,保存了一个副本,拷贝了intArr的值,
      在后面append中,因为容量(cap)不够,给intArr的index重新分配了空间,
      因为defer中保存的是intArr的值,所以defer打印出来的是原来的slice值
    func F1() {
       intArr := make([]int, 1)
       fmt.Println(&intArr[0], len(intArr), cap(intArr))
       defer f1(&intArr)
       intArr = append(intArr, 1)
       fmt.Println(&intArr[0], len(intArr), cap(intArr))
       return
    }
    
    func f1(ia *[]int) {
       intArr := *ia
       fmt.Println(&intArr[0], len(intArr), cap(intArr))
    }
    
    //结果
    0xc42000d2d0 1 1
    0xc42000d300 2 2
    0xc42000d300 2 2
    
    • 在defer中,保存了一个副本,拷贝了intArr的指针,
      在后面append中,因为容量(cap)不够,给intArr的index重新分配了空间,
      因为defer中保存的是intArr的指针,所以打印出来的是新的的slice值

    2. slice的扩容

    func F() {
         intArr := make([]int, 0, 0)
    
         intArr = append(intArr, 1)
         fmt.Println(&intArr[0], len(intArr), cap(intArr))
    
         intArr = append(intArr, 2)
         fmt.Println(&intArr[0], len(intArr), cap(intArr))
    
         intArr = append(intArr, 3)
         fmt.Println(&intArr[0], len(intArr), cap(intArr))
    
         intArr = append(intArr, 4)
         fmt.Println(&intArr[0], len(intArr), cap(intArr))
         return
    }
    
    //结果
    0xc42000d2d0 1 1
    0xc42000d300 2 2
    0xc4200cc660 3 4
    0xc4200cc660 4 4
    

    在对slice进行append等操作时,可能会造成slice的自动扩容。其扩容时的大小增长规则是:

    • 如果新的大小是当前大小2倍以上,则大小增长为新大小
    • 否则循环以下操作:如果当前大小小于1024,按每次2倍增长,否则每次按当前大小1/4增长。直到增长的大小超过或等于新大小。

    相关文章

      网友评论

        本文标题:golang slice学习

        本文链接:https://www.haomeiwen.com/subject/yzynvttx.html