欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

一、Slice數(shù)據(jù)結(jié)構(gòu)是什么?

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

二、詳細(xì)代碼

1.數(shù)據(jù)結(jié)構(gòu)

slice的結(jié)構(gòu)體由3部分構(gòu)成,Pointer 是指向一個(gè)數(shù)組的指針,len 代表當(dāng)前切片的長(zhǎng)度,cap 是當(dāng)前切片的容量。cap 總是大于等于 len 的。
通常我們?cè)趯?duì) slice 進(jìn)行 append 等操作時(shí),可能會(huì)造成slice的自動(dòng)擴(kuò)容。

代碼如下(示例):

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

2.擴(kuò)容原則

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

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

規(guī)則一:

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

1.當(dāng)小于1024個(gè)元素時(shí)

代碼如下(示例):

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

}

結(jié)果(示例):

結(jié)果

2.當(dāng)大于1024個(gè)元素時(shí)

代碼如下(示例):

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

}

結(jié)果(示例):

結(jié)果

此時(shí)容量Cap 增加了 1280 - 1024 = 256 ,也就是 1024 的 25 %
即 增長(zhǎng)因子就變成1.25,即每次增加原來(lái)容量的四分之一。

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

規(guī)則一:

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

1.簡(jiǎn)單理解內(nèi)存地址更換

代碼如下(示例):

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

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

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

}

結(jié)果(示例):

結(jié)果

此時(shí)容量Oth 指向原切片位置,而擴(kuò)容后的新的切片指向了新的位置,做的修改將無(wú)法影響原切片。

總結(jié)

通過(guò)以上兩個(gè)例子可以輕松了解在Golang中切片擴(kuò)容的主要形式。而因?yàn)榍衅牡讓右彩鞘窃谶B續(xù)的內(nèi)存塊中分配的,所以切片還能獲得索引、迭代以及為垃圾回收優(yōu)化的好處,非常適合我們深入學(xué)習(xí)。

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

相關(guān)文章

  • Go語(yǔ)言中的方法定義用法分析

    Go語(yǔ)言中的方法定義用法分析

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

    Go語(yǔ)言服務(wù)器開(kāi)發(fā)實(shí)現(xiàn)最簡(jiǎn)單HTTP的GET與POST接口

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

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

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

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

    作為一名開(kāi)發(fā)者,確保Go應(yīng)用中處理的數(shù)據(jù)是有效和準(zhǔn)確的非常重要,Go Validator是一個(gè)開(kāi)源的數(shù)據(jù)驗(yàn)證庫(kù),為Go結(jié)構(gòu)體提供強(qiáng)大且易于使用的數(shù)據(jù)驗(yàn)證功能,本篇文章將介紹Go Validator庫(kù)的主要特點(diǎn)以及如何在Go應(yīng)用中使用它來(lái)有效驗(yàn)證數(shù)據(jù)
    2023-12-12
  • 使用Go?http重試請(qǐng)求的示例

    使用Go?http重試請(qǐng)求的示例

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

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

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

    詳解Go語(yǔ)言中獲取文件路徑的不同方法與應(yīng)用場(chǎng)景

    在使用?Go?開(kāi)發(fā)項(xiàng)目時(shí),估計(jì)有不少人遇到過(guò)無(wú)法正確處理文件路徑的問(wèn)題,本文將嘗試從簡(jiǎn)單到復(fù)雜,詳細(xì)介紹?Go?中獲取路徑的不同方法及應(yīng)用場(chǎng)景,希望對(duì)大家有所幫助
    2024-02-02
  • 一文搞懂Go語(yǔ)言中defer關(guān)鍵字的使用

    一文搞懂Go語(yǔ)言中defer關(guān)鍵字的使用

    defer是golang中用的比較多的一個(gè)關(guān)鍵字,也是go面試題里經(jīng)常出現(xiàn)的問(wèn)題。今天就來(lái)整理一下關(guān)于defer的學(xué)習(xí)使用,希望對(duì)需要的朋友有所幫助
    2022-09-09
  • Golang學(xué)習(xí)之內(nèi)存逃逸分析

    Golang學(xué)習(xí)之內(nèi)存逃逸分析

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

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

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

最新評(píng)論