溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Go語言之切片Slice練習(xí)

發(fā)布時間:2020-06-16 17:19:10 來源:網(wǎng)絡(luò) 閱讀:1090 作者:故新 欄目:編程語言

切片Slice理論知識

  • 其本身并不是數(shù)組,它指向底層的數(shù)組
  • 作為編程數(shù)組的替代方案,可以關(guān)聯(lián)底層數(shù)組的局部或者全部
  • 為引用類型
  • 可以直接創(chuàng)建或從底層數(shù)組獲取生成
  • 使用len()獲取元素個數(shù),cap()獲取容量
  • 一般使用make()創(chuàng)建
  • 如果多個slice指向相同底層數(shù)組,其中一個的值改變會影響全部
  • make([]T, len, cap)
  • 其中,cap可以省略,則和len的值相同
  • len表示存數(shù)的元素個數(shù),cap表示容量

slice與底層數(shù)組的關(guān)系

Go語言之切片Slice練習(xí)

Reslice

  • Reslice時索引以被slice的切片為準(zhǔn)
  • 索引不可以超過被slice的切片的容量cap()的值
  • 索引越界不會導(dǎo)致底層數(shù)組的重新分配而是引發(fā)錯誤

Append

  • 可以在slice尾部追加元素
  • 可以將一個slice追加在另一個slice尾部
  • 如果最終長度未超過追加到slice的容量則返回原始slice
  • 如果超過追加到的slice的容量則將重新分配數(shù)組并拷貝原始數(shù)據(jù)

Copy

//切片slice  練習(xí)
package main

import "fmt"

func main() {
    //============先創(chuàng)建一個數(shù)組====
    // 創(chuàng)建數(shù)組,必須指明個數(shù)
    age := [4]int{}
    fmt.Println(age)

    //=========聲明一個切片Slice類型=====
    // 看見了吧,切片類型,是不需要指明 個數(shù)的
    // 記住,slice類型的底層,也是數(shù)組
    var s1 []float64
    fmt.Println(s1)

    //========方式一:利用已有的數(shù)組,來初始化s1
    sparkNodeCpu := [...]float64{4.5, 3.4, 2.3, 9.8, 10}
    s1 = sparkNodeCpu[3:5] //從下標(biāo)為3的元素,開始獲取
    fmt.Println("------------->\t", s1)
    s1 = sparkNodeCpu[1:] //從下標(biāo)為1的元素,獲取到 最后
    fmt.Println(s1)

    s1 = sparkNodeCpu[:4] //指定最后一個獲取的元素
    fmt.Println(s1)

    //========方式二:利用make關(guān)鍵字,來創(chuàng)建切片
    //make([]T, len, cap)
    //[]T,表示切片的類型
    //len,表示當(dāng)前元素的個數(shù),或者,初始化的個數(shù)
    //cap,由于切片的底層其實是數(shù)組,而數(shù)組在內(nèi)存里是一塊連續(xù)的空間,
    //      如make([]int, 3,10)  為了提升效率,一般先在內(nèi)存里創(chuàng)建
    // 一塊連續(xù)的內(nèi)存大小,為10,如果你的元素個數(shù)超過了10的話,
    //Go語言,會默認(rèn)將你現(xiàn)在的內(nèi)存空間,由10,增加到20,重新在內(nèi)存里找一塊連續(xù)的空間,分配20個空間
    // 如果又超過20的話,就分配40,就這么下去。因此,最好你知道你需要多大的內(nèi)存空間
    s2 := make([]int, 3, 10)
    fmt.Println(len(s2), cap(s2)) // 3  10

    s2a := make([]int, 3)           // 也可以不指定cap,這樣的話,cap的默認(rèn)值,就是len的長度
    fmt.Println(len(s2a), cap(s2a)) // 3  3

    //=======================Reslice========練習(xí)=====
    // 先聲明一個切片類型
    a := []rune{'a', 'b', 'c', 'd', 'e', 'f', 'j', 'k', 'u'}

    //以原切片a為基礎(chǔ),開始切
    //此時,你要注意了,新產(chǎn)生的切片s3的容量
    //下面的操作就是Reslice
    s3 := a[2:5] //表示,從下標(biāo)為2開始,到5結(jié)束,最大不能超過被切slice的cap容量7
    s3a := s3[3:5]

    fmt.Println("長度:\t", len(s3), "\t容量cap:\t", cap(s3))   //3 7
    fmt.Println("長度:\t", len(s3a), "\t容量cap:\t", cap(s3a)) //2 4
    fmt.Println(string(s3a))

    //=======================Append========練習(xí)=====
    slice1 := make([]int, 3, 6)                   //默認(rèn)值是全是0
    fmt.Printf("先打印出slice1的內(nèi)存地址:\t %p\n", slice1) // 0xc042078090

    //先追加3個元素
    slice1 = append(slice1, 1, 3, 5)

    //再打印出slice1的值,和 內(nèi)存地址
    fmt.Printf("%v  %p\n", slice1, slice1) //[0 0 0 1 3 5]  0xc042078090

    //繼續(xù)追加元素,查看,內(nèi)存地址,是否發(fā)生了變化
    slice1 = append(slice1, 4, 5, 6)

    // 超過了slice1的容量后,重新分配了內(nèi)存地址
    fmt.Printf("%v  %p\n", slice1, slice1) //[0 0 0 1 3 5 4 5 6]  0xc042056060

    fmt.Println("=======================================")
    //測試,當(dāng)多個切片都指向同一個底層數(shù)組時,并且多個切片有共同的元素時,如果其中一個元素,發(fā)生變化的話,
    //其他切片也會發(fā)生變化的
    appleSlice := []int{3, 4, 5, 9, 8, 7}
    bananaS := appleSlice[3:6]
    orangeS := appleSlice[2:5]

    //bananaS  orangeS  有兩個共同的元素
    fmt.Println(appleSlice) //[3 4 5 9 8 7]
    fmt.Println(bananaS)    //[9 8 7]
    fmt.Println(orangeS)    //[5 9 8]

    fmt.Println("=======================================")
    //假設(shè)bananaS切片里的元素,第1個元素,發(fā)生了變化的話,
    //測試,appleSlice,orangeS 是否也發(fā)生了變呢
    //我改動的是下標(biāo)為1,值為8的元素,將8改為了110,與此同時,其他切片中,8的值也全都改成了110了
    bananaS[1] = 110        //將下標(biāo)為1的元素,設(shè)置為110
    fmt.Println(appleSlice) //[3 4 5 9 110 7]
    fmt.Println(bananaS)    //[9 110 7]
    fmt.Println(orangeS)    //[5 9 110]

    fmt.Println("=======================================")
    // 注意,此時,orangeS,orangeS 依舊都執(zhí)行底層的數(shù)組appleSlice
    //還要注意下面的情形
    //利用Append方法
    bananaS = append(
        bananaS, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7)
    //此時,bananaS已經(jīng)不再指向appleSlice了,因為超過了appleSlice的容量

    //而是,指向了新的地址,此時,我們再修改bananaS
    bananaS[1] = 1110

    fmt.Println(appleSlice) //[3 4 5 9 110 7]
    //看見了把,僅僅是修改了自己的值,appleSlice,orangeS 并沒有發(fā)生變化
    fmt.Println(bananaS) //[9 1110 7 7 7 7 7 7 7 7 7 7 7 7 7 7]
    fmt.Println(orangeS) //[5 9 110]

    fmt.Println("=======================================")
    //=======================Copy========練習(xí)=====
    // copy(A,B) 是說,將B里的元素,拷貝到A里
    ftpNum := []int{4, 6, 7, 2, 3, 8, 9}
    sftpNum := []int{1, 2, 3}
    //將sftp
    copy(ftpNum, sftpNum) //注意,copy之后,就會將原先的值該了
    fmt.Println(ftpNum)
    fmt.Println(sftpNum)

    //截取拷貝
    copy(sftpNum[1:2], ftpNum[2:3])
    fmt.Println(ftpNum)
    fmt.Println(sftpNum)

}
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI