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

go的切片擴(kuò)容機(jī)制詳解

 更新時(shí)間:2023年04月03日 09:24:45   作者:走,我們?nèi)ゴ碉L(fēng)  
本文主要介紹了go的切片擴(kuò)容機(jī)制詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

切片的擴(kuò)容策略?如何擴(kuò)容?

擴(kuò)容策略:如果切片的容量小于 1024 個(gè)元素,于是擴(kuò)容的時(shí)候就翻倍增加容量。總?cè)萘繌脑瓉淼?個(gè)翻倍到現(xiàn)在的2個(gè)。

一旦元素個(gè)數(shù)超過 1024 個(gè)元素,那么增長(zhǎng)因子就變成 1.25 ,即每次增加原來容量的四分之一。

注意:擴(kuò)容擴(kuò)大的容量都是針對(duì)原來的容量而言的,而不是針對(duì)原來數(shù)組的長(zhǎng)度而言的。

舉一個(gè)擴(kuò)容策略例子:

func main() {
? ? slice := []int{10, 20, 30, 40}
? ? newSlice := append(slice, 50)
? ? fmt.Printf("Before slice = %v, Pointer = %p, len = %d, cap = %d\n", slice, &slice, len(slice), cap(slice))
? ? fmt.Printf("Before newSlice = %v, Pointer = %p, len = %d, cap = %d\n", newSlice, &newSlice, len(newSlice), cap(newSlice))
? ? newSlice[1] += 10
? ? fmt.Printf("After slice = %v, Pointer = %p, len = %d, cap = %d\n", slice, &slice, len(slice), cap(slice))
? ? fmt.Printf("After newSlice = %v, Pointer = %p, len = %d, cap = %d\n", newSlice, &newSlice, len(newSlice), cap(newSlice))
}

// result?
Before slice = [10 20 30 40], Pointer = 0xc4200b0140, len = 4, cap = 4
Before newSlice = [10 20 30 40 50], Pointer = 0xc4200b0180, len = 5, cap = 8
After slice = [10 20 30 40], Pointer = 0xc4200b0140, len = 4, cap = 4
// 相加的數(shù)是在新的切片上相加的
After newSlice = [10 30 30 40 50], Pointer = 0xc4200b0180, len = 5, cap = 8

 從結(jié)果我們可以看出,新切片和之前的切片已經(jīng)不同了,因?yàn)樾碌那衅牧艘粋€(gè)值,并沒有影響到原來的數(shù)組,新切片指向的數(shù)組是一個(gè)全新的數(shù)組,并且cap容量也發(fā)生了變化。

那么到底是新數(shù)組還是老數(shù)組呢?
擴(kuò)容之后數(shù)組就一定是新的嗎?其實(shí)是分兩種情況。

第一種情況:

func main() {
? ? array := [4]int{10, 20, 30, 40}
? ? slice := array[0:2]
? ? newSlice := append(slice, 50)
? ? fmt.Printf("Before slice = %v, Pointer = %p, len = %d, cap = %d\n", slice, &slice, len(slice), cap(slice))
? ? fmt.Printf("Before newSlice = %v, Pointer = %p, len = %d, cap = %d\n", newSlice, &newSlice, len(newSlice), cap(newSlice))
? ? newSlice[1] += 10
? ? fmt.Printf("After slice = %v, Pointer = %p, len = %d, cap = %d\n", slice, &slice, len(slice), cap(slice))
? ? fmt.Printf("After newSlice = %v, Pointer = %p, len = %d, cap = %d\n", newSlice, &newSlice, len(newSlice), cap(newSlice))
? ? fmt.Printf("After array = %v\n", array)
}

// result
? ? Before slice = [10 20], Pointer = 0xc4200c0040, len = 2, cap = 4
? ? Before newSlice = [10 20 50], Pointer = 0xc4200c0060, len = 3, cap = 4
? ? After slice = [10 30], Pointer = 0xc4200c0040, len = 2, cap = 4
? ? After newSlice = [10 30 50], Pointer = 0xc4200c0060, len = 3, cap = 4
? ? After array = [10 30 50 40]

通過這個(gè)結(jié)果可以明顯的看出,修改新切片的值居然影響到了老切片的值了,擴(kuò)容以后并沒有新建一個(gè)新的數(shù)組,并且append操作也改變了原來數(shù)組的值,如果原數(shù)組上有多個(gè)切片,那么這些切片都會(huì)影響,產(chǎn)生了莫名的bug!

這種情況也極容易出現(xiàn)在字面量創(chuàng)建切片時(shí)候,第三個(gè)參數(shù) cap 傳值的時(shí)候,如果用字面量創(chuàng)建切片,cap 并不等于指向數(shù)組的總?cè)萘?,那么這種情況就會(huì)發(fā)生。

注意:建議用字面量創(chuàng)建切片的時(shí)候,cap 的值一定要保持清醒,避免共享原數(shù)組導(dǎo)致的 bug。

第二種情況:

第二種情況就是擴(kuò)容策略的例子了,在擴(kuò)容之后產(chǎn)生了新的切片,因?yàn)樵瓟?shù)組的容量達(dá)到了最大值,再擴(kuò)容都會(huì)開出一片新的內(nèi)存,把原來的值拷貝過來,再進(jìn)行后續(xù)操作也不會(huì)影響原數(shù)組。

總結(jié):時(shí)刻保持cap的清醒,推薦使用第二種情況的擴(kuò)容策略

到此這篇關(guān)于go的切片擴(kuò)容機(jī)制詳解的文章就介紹到這了,更多相關(guān)go 切片擴(kuò)容 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入探究Golang中flag標(biāo)準(zhǔn)庫的使用

    深入探究Golang中flag標(biāo)準(zhǔn)庫的使用

    在本文中,我們將深入探討 flag 標(biāo)準(zhǔn)庫的實(shí)現(xiàn)原理和使用技巧,以幫助讀者更好地理解和掌握該庫的使用方法,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2023-04-04
  • 教你用go語言實(shí)現(xiàn)比特幣交易功能(Transaction)

    教你用go語言實(shí)現(xiàn)比特幣交易功能(Transaction)

    每一筆比特幣交易都會(huì)創(chuàng)造輸出,輸出都會(huì)被區(qū)塊鏈記錄下來。給某個(gè)人發(fā)送比特幣,實(shí)際上意味著創(chuàng)造新的 UTXO 并注冊(cè)到那個(gè)人的地址,可以為他所用,今天通過本文給大家分享go語言實(shí)現(xiàn)比特幣交易功能,一起看看吧
    2021-05-05
  • Go設(shè)計(jì)模式之原型模式講解和代碼示例

    Go設(shè)計(jì)模式之原型模式講解和代碼示例

    原型是一種創(chuàng)建型設(shè)計(jì)模式,使你能夠復(fù)制對(duì)象,甚至是復(fù)雜對(duì)象,而又無需使代碼依賴它們所屬的類,本文將通過代碼示例示例給大家講解一下Go 原型模式,感興趣的小伙伴可以參考閱讀
    2023-07-07
  • Go 語言中的空接口(推薦)

    Go 語言中的空接口(推薦)

    這篇文章主要介紹了Go 語言中的空接口的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Goland IDEA項(xiàng)目多開設(shè)置方式

    Goland IDEA項(xiàng)目多開設(shè)置方式

    這篇文章主要介紹了Goland IDEA項(xiàng)目多開設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • golang?gorm的預(yù)加載及軟刪硬刪的數(shù)據(jù)操作示例

    golang?gorm的預(yù)加載及軟刪硬刪的數(shù)據(jù)操作示例

    這篇文章主要介紹了golang?gorm的預(yù)加載及軟刪硬刪的數(shù)據(jù)操作示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • go語言if/else語句簡(jiǎn)單用法示例

    go語言if/else語句簡(jiǎn)單用法示例

    這篇文章主要介紹了go語言if/else語句用法,結(jié)合實(shí)例形式分析了go語言if else語句的判定與流程控制技巧,需要的朋友可以參考下
    2016-05-05
  • 秒懂Golang匿名函數(shù)

    秒懂Golang匿名函數(shù)

    所謂匿名函數(shù),就是沒有名字的函數(shù),本文重點(diǎn)給大家介紹Golang匿名函數(shù)的相關(guān)知識(shí),通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • Go 切片導(dǎo)致內(nèi)存泄露的幾種原因

    Go 切片導(dǎo)致內(nèi)存泄露的幾種原因

    某些情況下,對(duì)一個(gè)已存在的切片或數(shù)組進(jìn)行切分操作可能會(huì)導(dǎo)致內(nèi)存泄漏,本文主要介紹了Go 切片導(dǎo)致內(nèi)存泄露的幾種原因,感興趣的可以了解一下
    2023-05-05
  • Golang 文件操作:刪除指定的文件方式

    Golang 文件操作:刪除指定的文件方式

    這篇文章主要介紹了Golang 文件操作:刪除指定的文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04

最新評(píng)論