go6---slice切片


package main

/*
切片Slice
其本身並不是數組,它指向底層的數組
作為變長數組的替代方案,可以關聯底層數組的局部或全部
為引用類型
可以直接創建或從底層數組獲取生成
使用len()獲取元素個數,cap()獲取容量
一般使用make()創建
如果多個slice指向相同底層數組,其中一個的值改變會影響全部
make([]T, len, cap)
其中cap可以省略,則和len的值相同
len表示存數的元素個數,cap表示容量

用new創建數組的時候是一個指向數組的指針。
*/

import (
    "fmt"
)

func main() {
    var slice1 []int //中括號里面是數字或者3個點就表示數組,
    //中括號里面既不是數字也不是3個點就表示是slice不是數組
    fmt.Println(slice1) //[],slice的底層也是數組保存的,打印也是數組的格式,

    a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    fmt.Println(a) //[1 2 3 4 5 6 7 8 9 0]

    s1 := a[2]      //一個slice
    fmt.Println(s1) //3

    s2 := a[5:10]   //數組的索引從5到9,包頭不包尾,//一個slice
    fmt.Println(s2) //[6 7 8 9 0]

    s3 := a[5:len(a)] //數組的索引從5到長度減一,包頭不包尾,//一個slice
    fmt.Println(s3)   //[6 7 8 9 0]

    s4 := a[5:]     //數組的索引從5到尾部,//一個slice
    fmt.Println(s4) //[6 7 8 9 0]

    s5 := a[:5]     //數組的索引從開頭到索引為4,//一個slice
    fmt.Println(s5) //[1 2 3 4 5]

    s11 := make([]int, 3) //初始化3個元素,並放在slice所指向的數組中,
    fmt.Println(s11)      //    [0 0 0]

    s22 := make([]int, 3, 10) //初始化3個元素,slice指向的是一個數組,數組是一塊連續的內存,
    //數組不能動態修改長度, 10第三個參數是數組的容量,現在是3個,但是總共可以有10個,當超出10個后
    //會重新分配連續的內存塊(內存地址改變了)(重新分配內存的效率低),並且容量擴大一倍成20,
    fmt.Println(s22)                //    [0 0 0]
    fmt.Println(len(s22), cap(s22)) //    3,10

    //slice是引用類型的並且可以擴容的數組

    a1 := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}
    s33 := a1[2:5]           //一個slice
    fmt.Println(s33)         //    [99 100 101]
    fmt.Println(string(s33)) //    cde

    /*
        Reslice
        Reslice時索引以被slice的切片為准
        索引不可以超過被slice的切片的容量cap()值
        索引越界不會導致底層數組的重新分配而是引發錯誤
    */
    //從slice中獲取slice
    s44 := s33[1:3]          //一個slice
    fmt.Println(s44)         //[100 101]
    fmt.Println(string(s44)) //de

    /*
        Append
        可以在slice尾部追加元素
        可以將一個slice追加在另一個slice尾部
        如果最終長度未超過追加到slice的容量則返回原始slice
        如果超過追加到的slice的容量則將重新分配數組並拷貝原始數據
    */

    s55 := make([]int, 3, 6)        //3個元素容量為6的slice
    fmt.Printf("%v,%p\n", s55, s55) //[0 0 0],0xc04200e2a0
    s55 = append(s55, 1, 2, 3)
    fmt.Printf("%v,%p\n", s55, s55) //[0 0 0 1 2 3],0xc04200e2a0,沒有超過容量不重新分配內存地址
    s55 = append(s55, 1, 2, 3)
    fmt.Printf("%v,%p\n", s55, s55) //[0 0 0 1 2 3 1 2 3],0xc04203a120,超過容量重新分配內存地址

    a2 := [...]int{1, 2, 3, 4, 5}
    s66 := a2[2:5] //[3 4 5],不顯示的加容量,則容量就是此時slice中元素的個數3,
    s77 := a2[1:3] // [2 3]
    fmt.Println(s66, s77)
    s66[0] = 9
    fmt.Println(s66, s77) //[9 4 5] [2 9],slice指向一個底層的數組,其中一個改變另外一個也改變,
    //如果超過slice的容量會重新分配內存,此時改變這個slice其他的slice就不會改變了
    s66 = append(s66, 1, 2, 3, 2, 3, 2, 3, 4, 3, 4)
    s66[0] = 99
    fmt.Println(s66, s77) //[99 4 5 1 2 3 2 3 2 3 4 3 4] [2 9]

    //slice的copy函數
    s88 := []int{1, 2, 3, 4, 5, 6}
    s99 := []int{7, 8, 9}
    copy(s88, s99)        //左邊是拷貝到的元素,后面是被拷貝的元素,吧前三個元素拷貝到s88的前三個
    fmt.Println(s88, s99) //[7 8 9 4 5 6] [7 8 9]

    ss11 := []int{1, 2, 3, 4, 5, 6}
    ss22 := []int{7, 8, 9}
    copy(ss22, ss11)
    fmt.Println(ss11, ss22) //[1 2 3 4 5 6] [1 2 3],ss22只有3個元素,則只接收3個元素逇拷貝

    ss33 := []int{1, 2, 3, 4, 5, 6}
    ss44 := []int{7, 8, 9}
    copy(ss33, ss44[1:2])      //部分拷貝
    copy(ss33[2:4], ss44[1:2]) //指定拷貝到哪里
    fmt.Println(ss33, ss44)    //[1 2 3 4 5 6] [1 2 3],ss22只有3個元素,則只接收3個元素逇拷貝

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM