亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺談Golang?Slice切片如何擴容的實現(xiàn)

 更新時間:2022年02月22日 09:19:55   作者:頭禿貓輕王  
本文主要介紹了淺談Golang?Slice切片如何擴容的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、Slice數(shù)據結構是什么?

切片(slice)是 Golang 中一種比較特殊的數(shù)據結構,這種數(shù)據結構更便于使用和管理數(shù)據集合。切片是圍繞動態(tài)數(shù)組的概念構建的,可以按需自動增長和縮小。切片(slice)是可以看做是一個長度可變的數(shù)組。
切片(slice)自身并不是動態(tài)數(shù)組或者數(shù)組指針。它內部實現(xiàn)的數(shù)據結構通過指針引用底層數(shù)組,設定相關屬性將數(shù)據讀寫操作限定在指定的區(qū)域內。
切片(slice)是對數(shù)組一個連續(xù)片段的引用,所以切片是一個引用類型。

二、詳細代碼

1.數(shù)據結構

slice的結構體由3部分構成,Pointer 是指向一個數(shù)組的指針,len 代表當前切片的長度,cap 是當前切片的容量。cap 總是大于等于 len 的。
通常我們在對 slice 進行 append 等操作時,可能會造成slice的自動擴容。

代碼如下(示例):

type slice struct {
	array unsafe.Pointer
	len int
	cap int
}

2.擴容原則

  • 如果切片的容量小于1024個元素,那么擴容的時候slice的cap就乘以2;一旦元素個數(shù)超過1024個元素,增長因子就變成1.25,即每次增加原來容量的四分之一。
  • 如果擴容之后,還沒有觸及原數(shù)組的容量,那么,切片中的指針指向的位置,就還是原數(shù)組,如果擴容之后,超過了原數(shù)組的容量,那么,Go就會開辟一塊新的內存,把原來的值拷貝過來,這種情況絲毫不會影響到原數(shù)組。

3.如何理解擴容規(guī)則一

規(guī)則一:

如果切片的容量小于1024個元素,那么擴容的時候slice的cap就乘以2;一旦元素個數(shù)超過1024個元素,增長因子就變成1.25,即每次增加原來容量的四分之一。

1.當小于1024個元素時

代碼如下(示例):

func main() {
	// 建立容量為 2 的 切片
	addCap := make([]string, 0, 2)
	// 插入一個數(shù),占一個容量
	addCap = append(addCap, "1")
	// 打印此時的地址
	fmt.Println("addCap 1", addCap, cap(addCap), &addCap[0])
	// 插入一個數(shù),占一個容量
	// 再打印此時的地址
	addCap = append(addCap, "1")
	fmt.Println("addCap 2", addCap, cap(addCap), &addCap[0])
	// 插入一個數(shù),占一個容量
	// 再打印此時的地址
	addCap = append(addCap, "1")
	// 此時三個數(shù)已經超出容量,那么切片容量將擴容,此時地址也將變成新的地址
	fmt.Println("addCap 3", addCap, cap(addCap), &addCap[0])

}

結果(示例):

結果

2.當大于1024個元素時

代碼如下(示例):

func main() {
	// 建立容量為 1022 的 切片
	addCap1024 := make([]int, 1022, 1024)
	// 插入一個數(shù),占一個容量 容量 1023
	addCap1024 = append(addCap1024, 1)
	// 打印此時的地址
	fmt.Println("addCap1024 1", cap(addCap1024), &addCap1024[0])
	// 插入一個數(shù),占一個容量
	// 再打印此時的地址
	addCap1024 = append(addCap1024, 1)
	fmt.Println("addCap1024 2", cap(addCap1024), &addCap1024[0])
	// 插入一個數(shù),占一個容量
	// 再打印此時的地址
	addCap1024 = append(addCap1024, 1)
	// 此時三個數(shù)已經超出容量1024,那么切片容量將擴容,此時地址也將變成新的地址
	fmt.Println("addCap1024 3", cap(addCap1024), &addCap1024[0])

}

結果(示例):

結果

此時容量Cap 增加了 1280 - 1024 = 256 ,也就是 1024 的 25 %
即 增長因子就變成1.25,即每次增加原來容量的四分之一。

4.如何理解擴容規(guī)則二

規(guī)則一:

如果擴容之后,還沒有觸及原數(shù)組的容量,那么,切片中的指針指向的位置,就還是原數(shù)組,如果擴容之后,超過了原數(shù)組的容量,那么,Go就會開辟一塊新的內存,把原來的值拷貝過來,這種情況絲毫不會影響到原數(shù)組。

1.簡單理解內存地址更換

代碼如下(示例):

func main() {
	// 建立容量為 2 的 切片
	addCap := make([]string, 0, 2)
	// 插入一個數(shù),占一個容量
	addCap = append(addCap, "1")
	// 打印此時的地址
	fmt.Println("addCap 1", addCap, cap(addCap), &addCap[0])
	// 插入一個數(shù),占一個容量
	// 再打印此時的地址
	addCap = append(addCap, "1")
	fmt.Println("addCap 2", addCap, cap(addCap), &addCap[0])
	// 將 oth 的指針指向切片地址
	// 再打印此時的地址 和 addCap 一樣,即未觸及容量時,還是原數(shù)組
	oth := addCap[0:1]
	fmt.Println("oth 1",oth,cap(oth),&oth[0])

	//此時修改原數(shù)組 oth 所指向的地址不變,但第一個數(shù)的值已經更改 3
	addCap[0] = "3"
	fmt.Println("oth 2",oth,cap(oth),&oth[0])

	// 插入一個數(shù),占一個容量
	// 再打印此時的地址
	addCap = append(addCap, "1")
	//此時再修改 已經是擴容后的新地址 原數(shù)組將保持不變 即oth 所指向的地址的值不變
	addCap[0] = "4"
	// 此時三個數(shù)已經超出容量,那么切片容量將擴容,此時地址也將變成新的地址,第一個數(shù)也將修改為 4
	fmt.Println("addCap 3", addCap, cap(addCap), &addCap[0])
	// 但 oth 依然保留著原數(shù)組的指針地址,所以依然還是 3
	fmt.Println("oth 3",oth,cap(oth),&oth[0])

}

結果(示例):

結果

此時容量Oth 指向原切片位置,而擴容后的新的切片指向了新的位置,做的修改將無法影響原切片。

總結

通過以上兩個例子可以輕松了解在Golang中切片擴容的主要形式。而因為切片的底層也是是在連續(xù)的內存塊中分配的,所以切片還能獲得索引、迭代以及為垃圾回收優(yōu)化的好處,非常適合我們深入學習。

到此這篇關于淺談Golang Slice切片如何擴容的實現(xiàn)的文章就介紹到這了,更多相關Golang Slice切片擴容內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Go語言中的方法定義用法分析

    Go語言中的方法定義用法分析

    這篇文章主要介紹了Go語言中的方法定義用法,實例分析了方法的定義及使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • Go語言服務器開發(fā)實現(xiàn)最簡單HTTP的GET與POST接口

    Go語言服務器開發(fā)實現(xiàn)最簡單HTTP的GET與POST接口

    這篇文章主要介紹了Go語言服務器開發(fā)實現(xiàn)最簡單HTTP的GET與POST接口,實例分析了Go語言http包的使用技巧,需要的朋友可以參考下
    2015-02-02
  • Go?語言?net/http?包使用之HTTP?服務器、客戶端與中間件詳解

    Go?語言?net/http?包使用之HTTP?服務器、客戶端與中間件詳解

    Go 語言標準庫中的net/http包十分的優(yōu)秀,提供了非常完善的 HTTP 客戶端與服務端的實現(xiàn),僅通過幾行代碼就可以搭建一個非常簡單的 HTTP 服務器,本文給大家介紹Go語言net/http包使用之HTTP服務器、客戶端與中間件的操作,感興趣的朋友一起看看吧
    2025-05-05
  • 使用Go Validator有效驗證數(shù)據示例分析

    使用Go Validator有效驗證數(shù)據示例分析

    作為一名開發(fā)者,確保Go應用中處理的數(shù)據是有效和準確的非常重要,Go Validator是一個開源的數(shù)據驗證庫,為Go結構體提供強大且易于使用的數(shù)據驗證功能,本篇文章將介紹Go Validator庫的主要特點以及如何在Go應用中使用它來有效驗證數(shù)據
    2023-12-12
  • 使用Go?http重試請求的示例

    使用Go?http重試請求的示例

    開發(fā)中對于http請求是經常遇到,一般可能網絡延遲或接口返回超時,這篇文章主要介紹了使用Go?http重試請求的示例,需要的朋友可以參考下
    2022-08-08
  • 一文帶你深入了解Go語言中切片的奧秘

    一文帶你深入了解Go語言中切片的奧秘

    切片是數(shù)組的一個引用,因此切片是引用類型。但自身是結構體,值拷貝傳遞。本文將通過示例帶大家一起探索一下Go語言中切片的奧秘,感興趣的可以了解一下
    2022-11-11
  • 詳解Go語言中獲取文件路徑的不同方法與應用場景

    詳解Go語言中獲取文件路徑的不同方法與應用場景

    在使用?Go?開發(fā)項目時,估計有不少人遇到過無法正確處理文件路徑的問題,本文將嘗試從簡單到復雜,詳細介紹?Go?中獲取路徑的不同方法及應用場景,希望對大家有所幫助
    2024-02-02
  • 一文搞懂Go語言中defer關鍵字的使用

    一文搞懂Go語言中defer關鍵字的使用

    defer是golang中用的比較多的一個關鍵字,也是go面試題里經常出現(xiàn)的問題。今天就來整理一下關于defer的學習使用,希望對需要的朋友有所幫助
    2022-09-09
  • Golang學習之內存逃逸分析

    Golang學習之內存逃逸分析

    內存逃逸分析是go的編譯器在編譯期間,根據變量的類型和作用域,確定變量是堆上還是棧上。本文將帶大家分析一下Golang中的內存逃逸,需要的可以了解一下
    2023-01-01
  • 利用go語言實現(xiàn)查找二叉樹中的最大寬度

    利用go語言實現(xiàn)查找二叉樹中的最大寬度

    這篇文章主要介紹了利用go語言實現(xiàn)查找二叉樹中的最大寬度,文章圍繞主題展開詳細介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05

最新評論