詳解go語言的array和slice 【二】

來源:互聯網
上載者:User

標籤:位元組   png   www.   .com   ref   image   ges   注意   對比   

  上一篇  詳解go語言的array和slice 【一】已經講解過,array和slice的一些基本用法,使用array和slice時需要注意的地方,特別是slice需要注意的地方比較多。上一篇的最後講解到建立新的slice時使用第三個索引來限制slice的容量,在操作新slice時,如果新slice的容量大於長度時,添加新元素依然後使源的相應元素改變。這一篇裡我會講解到如何避免這些問題,以及迭代、和做為方法參數方面的知識點。

slice的長度和容量設定為同一個值

  如果在建立新的slice時我們把他的長度和容量的值設定為樣的值,那麼在append新元素時,底層會建立一個新的array並把之前的值複製過去。這樣就不會影響之前共同的底層array了。

    // 建立一個容量和長度均為6的slice    slice1 := []int{5, 23, 10, 2, 61, 33}    // 對slices1進行切片,長度為2容量為3    slice2 := slice1[1:3:3]    fmt.Println("cap", cap(slice2))    fmt.Println("slice2", slice2)    //修改一個共同指向的元素    //兩個slice的值都會修改    slice2[0] = 11111    fmt.Println("slice1", slice1)    fmt.Println("slice2", slice2)    // 增加一個元素    slice2 = append(slice2, 55555)    fmt.Println("slice1: ", slice1)    fmt.Println("slice2: ", slice2)

  輸出結果

cap 2slice2 [23 10]slice1 [5 11111 10 2 61 33]slice2 [11111 10]slice1:  [5 11111 10 2 61 33]slice2:  [11111 10 55555]

  代碼中的長度和容量是一樣的,長度和容量的計算公式看我的上一篇部落格。增加一個元素後,原來共同指向的底層資料是沒有變的。因為slice2的底層array被重新賦值了。

迭代slice

  go語言內建一個關鍵字range用於迭代集合,當然他也可以迭代slice,也可以使用  _  來忽略我們不關心的元素,但是如果只關心index則不需這麼寫 for index,_ := range slice1。下在給出完整代碼

    // 建立一個容量和長度均為6的slice    slice1 := []int{5, 23, 10, 2, 61, 33}    for index, value := range slice1 {        fmt.Println("index: ", index, " value: ", value)    }    // 可以忽略我們不關心的元素    // 只關心value    for _, value := range slice1 {        fmt.Println("value ", value)    }    // 只關心index, 可以不用 _    for index := range slice1 {        fmt.Println("index: ", index)    }

 

   需要注意的是rang 迭代的value值並是一個複本,我們可以對比一下迭代的value和原slice內相應index下value的地址:

    // 建立一個容量和長度均為6的slice    slice1 := []int{5, 23, 10, 2, 61, 33}    for index, value := range slice1 {        fmt.Println("index: ", index, " value address : ", &value, " slice1 value address", &slice1[index])    }

  輸出結果

index:  0  value address :  0xc04204e088  slice1 value address 0xc04206a030index:  1  value address :  0xc04204e088  slice1 value address 0xc04206a038index:  2  value address :  0xc04204e088  slice1 value address 0xc04206a040index:  3  value address :  0xc04204e088  slice1 value address 0xc04206a048index:  4  value address :  0xc04204e088  slice1 value address 0xc04206a050index:  5  value address :  0xc04204e088  slice1 value address 0xc04206a058

  slice1中value的地址是不斷變化的。而迭代的value值的地址沒有變化,這是因為value是一個變數,為次迭代的時候賦不同的值。我們把代碼寫成下面這樣,你就清楚了

    var index, value int    for index, value = range slice1 {        fmt.Println("index: ", index, &index, " value address : ", &value, " slice1 value address", &slice1[index])    }

   除了使用rang 也可以使用傳統的for迴圈來做迭代

    slice1 := []int{5, 23, 10, 2, 61, 33}        for i, len := 1, len(slice1); i < len; i++ {        fmt.Println("index: ", i, " value:", slice1[i])    }

 

 slice作為方法參數

   由於slice的特殊結構,有一個指標指向一個數組

    s := make([]int, 2, 5)    fmt.Println("len: ", len(s))    fmt.Println("cap: ", cap(s))    s = append(s, 2)    s[0] = 12

 

  所以,slice做為方法的參數傳遞時,只會複製slice本身而不會複製slice底層的array.如果我們建立一個int類型有100萬長度的slice ,把他傳遞給一個方法時,只需要複製24個位元組就夠了。指標需要8個,長度和容量都是8個。

const size int = 1000 * 1000func main() {    slice0 := make([]int, size)    fmt.Println("slice0 len: ", len(slice0), " cap :", cap(slice0))    doSomeThing(slice0)}func doSomeThing(s []int) {    fmt.Println(len(s))}

 

 

詳解go語言的array和slice 【二】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.