go語言---slice

來源:互聯網
上載者:User

標籤:使用   tps   append   poi   問題:   方法   .net   demo   地址空間   

go語言---slice78893420一.數組切片的使用:
//1.基於數組建立數組切片    var array [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}    var sliceMy = array[1:7] //array[startIndex:endIndex] 不包含endIndex    //2.直接建立數組切片    slice2 := make([]int, 5, 10)    //3.直接建立並初始化數組切片    slice3 := []int{1, 2, 3, 4, 5, 6}    //4.基於數組切片建立數組切片    slice5 := slice3[:4]    //5.遍曆數組切片    for i, v := range slice3 {        fmt.Println(i, v)    }    //6.len()和cap()    var len = len(slice2)  //數組切片的長度    var cap = cap(sliceMy) //數組切片的容量    fmt.Println("len(slice2) =", len)    fmt.Println("cap(slice) =", cap)    //7.append() 會產生新的數組切片    slice4 := append(slice2, 6, 7, 8)    slice4 = append(slice4, slice3...)    fmt.Println(slice4)    fmt.Println(slice5)    //8.copy() 如果進行操作的兩個數組切片元素個數不一致,將會按照個數較小的數組切片進行複製    copy(slice2, slice3) //將slice3的前五個元素複製給slice2    fmt.Println(slice2, slice3)
二.數組切片資料結構分析:

數組切片slice的資料結構如下,一個指向真實array地址的指標ptr,slice的長度len和容量cap

// slice 資料結構type slice struct {    array unsafe.Pointer     len   int                cap   int            }

當傳參時,函數接收到的參數是數組切片的一個複製,雖然兩個是不同的變數,但是它們都有一個指向同一個地址空間的array指標,當修改一個數組切片時,另外一個也會改變,所以數組切片看起來是引用傳遞,其實是值傳遞。

三.append()方法解析:

3.1 數組切片不擴容的情況

運行以下代碼思考一個問題:s1和s2是指向同一個底層數組嗎?

func main() {    array := [20]int{1, 2, 3, 4, 5, 6, 7, 8, 9}    s1 := array[:5]    s2 := append(s1, 10)    fmt.Println("s1 =", s1)    fmt.Println("s2 =", s2)    s2[0] = 0    fmt.Println("s1 =", s1)    fmt.Println("s2 =", s2)}

輸出結果:
s1 = [1 2 3 4 5]
s2 = [1 2 3 4 5 10]
s1 = [0 2 3 4 5]
s2 = [0 2 3 4 5 10]
由第一行和第二行結果看來,似乎這是指向兩個不同的數組;但是當修改了s2,發現s1也跟著改變了,這又表明二者是指向同一個數組。到底真相是怎樣的呢?
運行以下代碼:

import (    "fmt"    "unsafe") type Slice struct {    ptr unsafe.Pointer // Array pointer    len int            // slice length    cap int            // slice capacity} func main() {    array := [20]int{1, 2, 3, 4, 5, 6, 7, 8, 9}    s1 := array[:5]    s2 := append(s1, 10)    s2[0] = 0    // 把slice轉換成自訂的 Slice struct    slice1 := (*Slice)(unsafe.Pointer(&s1))    fmt.Printf("ptr:%v len:%v cap:%v \n", slice1.ptr, slice1.len, slice1.cap)    slice2 := (*Slice)(unsafe.Pointer(&s2))    fmt.Printf("ptr:%v len:%v cap:%v \n", slice2.ptr, slice2.len, slice2.cap)}

輸出結果:
ptr:0xc04205e0a0 len:5 cap:20
ptr:0xc04205e0a0 len:6 cap:20

由結果可知:ptr指標儲存的是數組中的首地址的值,並且這兩個值相同,所以s1和s2確實是指向同一個底層數組。但是,這兩個數組切片的元素不同,這個可以根據首地址和數組切片長度len來確定不同的數組切片應該包含哪些元素,因為s1和s2雖然指向同一個底層數組,但是二者的len不同。通過這個demo,也驗證了數組切片傳參方式也是值傳遞。
3.2 數組切片擴容的情況:

運行以下代碼,思考與不擴容情況的不同之處,以及為什麼

func main() {    s1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}    s2 := append(s1, 10)    fmt.Println("s1 =", s1)    fmt.Println("s2 =", s2)    s2[0] = 0    fmt.Println("s1 =", s1)    fmt.Println("s2 =", s2)}

輸出結果:
s1 = [1 2 3 4 5 6 7 8 9]
s2 = [1 2 3 4 5 6 7 8 9 10]
s1 = [1 2 3 4 5 6 7 8 9]
s2 = [0 2 3 4 5 6 7 8 9 10]

根據結果我們發現,修改s2後,s1並未改變,這說明當append()後,s1和s2並未指向同一個底層數組,這又是為什麼呢?

同樣,我們接著運行以下代碼:

import (    "fmt"    "unsafe") type Slice struct {    ptr unsafe.Pointer // Array pointer    len int            // slice length    cap int            // slice capacity} func main() {    s1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}    s2 := append(s1, 10)    fmt.Println("s1 =", s1)    fmt.Println("s2 =", s2)    s2[0] = 0    fmt.Println("s1 =", s1)    fmt.Println("s2 =", s2)    // 把slice轉換成自訂的 Slice struct    slice1 := (*Slice)(unsafe.Pointer(&s1))    fmt.Printf("ptr:%v len:%v cap:%v \n", slice1.ptr, slice1.len, slice1.cap)    slice2 := (*Slice)(unsafe.Pointer(&s2))    fmt.Printf("ptr:%v len:%v cap:%v \n", slice2.ptr, slice2.len, slice2.cap)}

輸出結果:
s1 = [1 2 3 4 5 6 7 8 9]
s2 = [1 2 3 4 5 6 7 8 9 10]
s1 = [1 2 3 4 5 6 7 8 9]
s2 = [0 2 3 4 5 6 7 8 9 10]
ptr:0xc04207a000 len:9 cap:9
ptr:0xc04207c000 len:10 cap:18
由結果可知:append()後,s1和s2確實指向了不同的底層數組,並且二者的數組容量cap也不相同了。過程是這樣的:當append()時,發現數組容量不夠用,於是開闢了新的數組空間,cap變為原來的兩倍,s2指向了這個新的數組,所以當修改s2時,s1不受影響

go語言---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.