golang 數組與切片

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

通過下面幾個問題來更好理解golang 的數組和切片

  1. 類型

    數組是實值型別,將一個數組賦值給另一個數組時,傳遞的是一份拷貝。
    切片是參考型別,切片封裝的數組稱為該切片的底層數組。
    我們來看一段代碼

    //a是一個數組,注意數組是一個固定長度的,初始化時候必須要指定長度,不指定長度的話就是切片了a := [3]int{1, 2, 3}//b是數組,是a的一份拷貝b := a//c是切片,是參考型別,底層數組是ac := a[:]for i := 0; i < len(a); i++ {  a[i] = a[i] + 1}//改變a的值後,b是a的拷貝,b不變,c是引用,c的值改變fmt.Println(a) //[2,3,4]fmt.Println(b) //[1 2 3]fmt.Println(c) //[2,3,4]
  2. make
    make 只能用於slice, map 和 channel, 所以下面一段代碼產生了一個slice,是參考型別

    s1 := make([]int, 0, 3)for i := 0; i < cap(s1); i++ {    s1 = append(s1, i)}s2 := s1for i := 0; i < len(a); i++ {    s1[i] = s1[i] + 1}fmt.Println(s1)  //[1 2 3]fmt.Println(s2)  //[1 2 3]
  3. 當對slice append 超出底層數組的界限時

    //n1是n2的底層數組n1 := [3]int{1, 2, 3}n2 := n1[0:3]fmt.Println("address of items in n1: ")for i := 0; i < len(n1); i++ {    fmt.Printf("%p\n", &n1[i])}//address of items in n1://0xc20801e160//0xc20801e168//0xc20801e170fmt.Println("address of items in n2: ")for i := 0; i < len(n2); i++ {    fmt.Printf("%p\n", &n2[i])}//address of items in n2://0xc20801e160//0xc20801e168//0xc20801e170//對n2執行append操作後,n2超出了底層數組n1的jn2 = append(n2, 1)fmt.Println("address of items in n1: ")for i := 0; i < len(n1); i++ {    fmt.Printf("%p\n", &n1[i])}//address of items in n1://0xc20801e160//0xc20801e168//0xc20801e170fmt.Println("address of items in n2: ")for i := 0; i < len(n2); i++ {    fmt.Printf("%p\n", &n2[i])}//address of items in n2://0xc20803a2d0//0xc20803a2d8//0xc20803a2e0//0xc20803a2e8
  4. 引用“失效”
    實現了刪除slice最後一個item的函數

    func rmLast(a []int) {    fmt.Printf("[rmlast] the address of a is %p", a)    a = a[:len(a)-1]    fmt.Printf("[rmlast] after remove, the address of a is %p", a)}

    調用此函數後,發現原來的slice並沒有改變

    func main() {    xyz := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}    fmt.Printf("[main] the address of xyz is %p\n", xyz)    rmLast(xyz)    fmt.Printf("[main] after remove, the address of xyz is %p\n", xyz)    fmt.Printf("%v", xyz) //[1 2 3 4 5 6 7 8 9]}

    列印出來的結果如下:

    [main] the address of xyz is 0xc2080365f0[rmlast] the address of a is 0xc2080365f0[rmlast] after remove, the address of a is 0xc2080365f0[main] after remove, the address of xyz is 0xc2080365f0[1 2 3 4 5 6 7 8 9]

    這裡直接列印了slice的指標值,因為slice是參考型別,所以指標值都是相同的,我們換成列印slice的地址看下

    func rmLast(a []int) {    fmt.Printf("[rmlast] the address of a is %p", &a)    a = a[:len(a)-1]    fmt.Printf("[rmlast] after remove, the address of a is %p", &a)}func main() {    xyz := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}    fmt.Printf("[main] the address of xyz is %p\n", &xyz)    rmLast(xyz)    fmt.Printf("[main] after remove, the address of xyz is %p\n", &xyz)    fmt.Printf("%v", xyz) //[1 2 3 4 5 6 7 8 9]}

    結果:

    [main] the address of xyz is 0xc20801e1e0[rmlast] the address of a is 0xc20801e200[rmlast] after remove, the address of a is 0xc20801e200[main] after remove, the address of xyz is 0xc20801e1e0[1 2 3 4 5 6 7 8 9]

    這次可以看到slice作為函數參數傳入函數時,實際上也是拷貝了一份slice,因為slice本身是個指標,所以從現象來看,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.