[golang]slice的坑:從append到共享

go是宣揚(yáng)實(shí)用主義的語(yǔ)言,很多時(shí)候都把c中的最佳實(shí)踐直接規(guī)定成語(yǔ)法了。其中之一就是slice,簡(jiǎn)單但是非常容易踩坑。

先看一個(gè)小例子:

func main() {
    a := make([]int, 2, 2)
    a[0], a[1] = 1, 2

    b := append(a[0:1], 3)
    c := append(a[1:2], 4)

    fmt.Println(b,c)
}

在這個(gè)小例子中,原本是希望將a[0:1]作為b的前綴,然后追加上3;將a[1:2]作為c的前綴,然后追加上4。但實(shí)際上輸出結(jié)果并不是原本期望的[1 3] [2 4],而變成了[1 3] [3 4]。這是為什么呢?

我們知道數(shù)據(jù)結(jié)構(gòu)中數(shù)組是非常高效的,可以直接尋址,但是有個(gè)缺陷,難以擴(kuò)容。所以slice被設(shè)計(jì)為指向數(shù)組的指針,在需要擴(kuò)容時(shí),會(huì)將底層數(shù)組上的值復(fù)制到一個(gè)更大的數(shù)組上然后指向這個(gè)新數(shù)組。

slice有個(gè)特性是允許多個(gè)slice指向同一個(gè)底層數(shù)組,這是一個(gè)有用的特性,在很多場(chǎng)景下都能通過(guò)這個(gè)特性實(shí)現(xiàn) no copy 而提高效率。但共享同時(shí)意味著不安全。b在追加3時(shí)實(shí)際上覆蓋了a[1],導(dǎo)致c變成了[3 4]。

怎么解決呢?防止共享數(shù)據(jù)的出現(xiàn)問(wèn)題需要注意兩條,只讀和復(fù)制,或者統(tǒng)一歸納為不可變。

寫(xiě)法1,make出一個(gè)新slice,然后先copy前綴到新數(shù)組上再追加:

func main() {
    a := make([]int, 2, 2)
    a[0], a[1] = 1, 2

    b := make([]int, 1)
    copy(b, a[0:1])
    b = append(b, 3)

    c := make([]int, 1)
    copy(c, a[1:2])
    c = append(c, 4)

    fmt.Println(b, c)
}

寫(xiě)法2,利用go中slice的一個(gè)小眾語(yǔ)法,a[0:1:1] (源[起始index,終止index,cap終止index]),強(qiáng)迫追加時(shí)復(fù)制到新數(shù)組。

func main() {
    a := make([]int, 2, 2)
    a[0], a[1] = 1, 2

    b := append(a[0:1:1], 3)
    c := append(a[1:2:2], 4)

    fmt.Println(b, c)
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載自:https://halfrost.com/go_map_chapter_one/ https://half...
    HuJay閱讀 6,484評(píng)論 1 5
  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 32,329評(píng)論 2 89
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,715評(píng)論 19 139
  • 今天是大二第二學(xué)期的第一天,奔波了1天多的車(chē)程,于昨日下午5點(diǎn)多到了學(xué)校,簡(jiǎn)單地收拾了下宿舍,去學(xué)生街購(gòu)買(mǎi)了...
    Lancy蘭希閱讀 279評(píng)論 0 0
  • 今天外面真的好冷,本想就安靜的坐著等到下課,后來(lái)覺(jué)得還是把要辦的事做了吧!自己平時(shí)總是這樣,抱怨時(shí)間那么緊張,想出...
    李李和她的朋友閱讀 245評(píng)論 0 0

友情鏈接更多精彩內(nèi)容