Go指南_切片的長度與容量


源地址 https://tour.go-zh.org/moretypes/11

一、描述

切片擁有 長度 和 容量

切片的長度就是它所包含的元素個數。

切片的容量是從它的第一個元素開始數,到其底層數組元素末尾的個數。

切片 s 的長度和容量可通過表達式 len(s) 和 cap(s) 來獲取。

你可以通過重新切片來擴展一個切片,給它提供足夠的容量。試着修改示例程序中的切片操作,向外擴展它的容量,看看會發生什么。

 

二、程序運行過程

1,第一個輸出為[2,3,5,7,11,13],長度為6,容量為6;

2,左指針和右指針同時指向s[0],所以長度為0,容量為0;

3,左指針指向s[0],右指針指向s[4],由於切片概念是只包含左邊元素不包含右邊元素,所以長度為4,但左指針在s[0]處,走過0個元素,所以容量仍然為6;

4,在經歷步驟3切片后的基礎上,左指針指向s[2],右指針指向最右邊,所以長度為2,由於左指針走過兩個元素,離最右邊還剩4個元素,所以容量為4。

 

三、小結

本文內容最難理解的是切片的容量,我們可以把容量當做成總長度減去左指針走過的元素值,比如:

s[:0] ——> cap = 6 - 0 =6;

s[2:] ——> cap = 6 - 2 = 4。

 

四、append() 和 copy() 函數

如果想增加切片的容量,我們必須創建一個新的更大的切片並把原分片的內容都拷貝過來。

下面的代碼描述了從拷貝切片的 copy 方法和向切片追加新元素的 append 方法。

package main

import "fmt"

func main() {
   var numbers []int
   printSlice(numbers)

   /* 允許追加空切片 */
   numbers = append(numbers, 0)
   printSlice(numbers)

   /* 向切片添加一個元素 */
   numbers = append(numbers, 1)
   printSlice(numbers)

   /* 同時添加多個元素 */
   numbers = append(numbers, 2,3,4)
   printSlice(numbers)

   /* 創建切片 numbers1 是之前切片的兩倍容量*/
   numbers1 := make([]int, len(numbers), (cap(numbers))*2)

   /* 拷貝 numbers 的內容到 numbers1 */
   copy(numbers1,numbers)
   printSlice(numbers1)   
}

func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

 

這時我將第18行要增加的元素改為五個,我們可以看到len=7,cap=8

 

再進行舉例說明

 

新建切片並在里面追加元素

 

整體過程說明

  1. 創建numbers時,由於里面沒有加入任何元素,所以len=0 cap=0 slice=[]
  2. append(numbers, 0)時,向空切片numbers中追加了一個元素,所以len=1 cap=1 slice=[0]
  3. append(numbers, 1)時,向之前的切片numbers中追加了一個元素,按Slice擴容機制,cap翻倍后=2,所以len=2 cap=2 slice=[0 1]
  4. append(numbers, 2,3,4,)時,向之前的切片numbers中追加了三個元素,按Slice擴容機制,cap翻倍后2*3=6,所以len=5 cap=6 slice=[0 1 2 3 4]
  5. append(numbers, 5,6,7,8,9,10)時,向之前的切片numbers中追加了六個元素,按Slice擴容機制,cap翻倍后6*2=12,所以len=11 cap=12 slice=[0 1 2 3 4 5 6 7 8 9 10]
  6. 新建切片numbers2 := append(numbers,11)時,是像之前的切片numbers追加一個元素11,追加后長度為12,容量為12,所以不需要擴容,len=12 cap=12 slice=[0 1 2 3 4 5 6 7 8 9 10 11]
  7. 新建切片numbers3 := append(numbers,12)時,是像之前的切片numbers追加一個元素12,追加后長度為12,容量為12,所以不需要擴容,len=12 cap=12 slice=[0 1 2 3 4 5 6 7 8 9 10 12]
  8. 創建切片numbers1時,由於cap(numbers)*2,所以容量要翻倍,len=11 cap=24 slice=[0 1 2 3 4 5 6 7 8 9 10]

 

五、總結

由此可知,容量隨着底層數組長度的變化而不斷變化,如果底層數組長度為4,在添加了一個元素后變成5,則容量變為 4*2=8,如果len=12,cap=12,如果追加一個元素后,那么新的cap=2*7=14。

(切片這塊很神奇,我也只是把我遇到的總結下,如果有不足之處希望大家及時提出來,我好及時更新!)

 

六、參考資料

Golang中Slice的append詳解

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM