Go語言切片

Go語言切片是對數組的抽象。數組的長度不可改變,在特定場景中這樣的集合就不太適用,Go中提供了一種靈活,功能強悍的內置類型切片("動態數組"),與數組相比切片的長度是不固定的能夠追加元素,在追加時可能使切片的容量增大。數組

須要說明,slice 並非數組或數組指針。它經過內部指針和相關屬性引用數組片斷,以實現變長方案。app

切片定義

第一種,聲明一個切片:函數

var slice []int

切片定義並初始化spa

var slice0 []int = []int{1, 2, 3}
var slice1 = []int{1, 2, 3}

第二種,經過make來建立切片指針

var slice0 []int = make([]int, 10)
var slice1 = make([]int, 10)
var slice2 = make([]int, 10, 10)

第三種,經過 := 語法來定義切片code

slice0 := []int{}
slice1 := make([]int, 10)
slice2 := make([]int, 10, 10)

第四種,經過操做數組來建立切片blog

ar array = [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
var slice0 []int = array[2:8]

// 能夠簡寫爲 var slice []int = array[:end]
var slice1 []int = array[0:6]

// 能夠簡寫爲 var slice[]int = array[start:]
var slice2 []int = array[5:10]

// 能夠簡寫爲var slice []int = array[:]
var slice3 []int = array[0:len(array)]

// 去掉切片的最後一個元素
var slice4 = array[:len(array)-1]

第五種,經過兩個冒號建立切片,slice[x:y:z]切片實體[x:y],切片長度len = y-x,切片容量cap = z-x索引

package main

import (
    "fmt"
)

func main() {
    slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    slice1 := slice[6:8]
    fmt.Printf("slice1 : %v , len : %d , cap : %d\n", slice1, len(slice1), cap(slice1))
    slice2 := slice[2:6:8]
    fmt.Printf("slice2 : %v , len : %d , cap : %d\n", slice2, len(slice2), cap(slice2))
}

slice1[6:8],從第6位到第8位(返回[6 7]),長度len爲2,最大可擴充長度cap爲4class

slice2[2:6:8],從第2位到第6位(返回[2 3 4 5]),長度len爲4,最大可擴充長度cap爲6import

切片操做

切片長度,能夠由 len() 函數獲取切片長度。
切片容量,能夠由 cap() 函數獲取切片最長能夠達到多少。

package main

import "fmt"

func main() {
    // 經過初始化表達式構造,可以使用索引號。
    s1 := []int{0, 1, 2, 3, 8: 100}
    fmt.Println(s1, len(s1), cap(s1))

    // 使用 make 建立,指定 len 和 cap 值。
    s2 := make([]int, 6, 8)
    fmt.Println(s2, len(s2), cap(s2))

    // 省略 cap,至關於 cap = len。
    s3 := make([]int, 6)
    fmt.Println(s3, len(s3), cap(s3))
}

若是 slice == nil,那麼 len、cap 結果都等於 0。

切片追加,使用append() 函數向 slice 尾部添加數據,返回新的 slice

package main

import (
    "fmt"
)

func main() {

    var a = []int{1, 2, 3}

    // 一次 append 一個值
    b := append(a, 4)

    // 一次 append 多個值
    c := append(b, 5, 6, 7)

    // 一次 append 一個切片
    var d = []int{8, 9, 10}
    e := append(c, d...)

    fmt.Println(a, b, c, d, e)
}

切片拷貝,使用copy() 函數 copy 在兩個 slice 間複製數據,複製長度以 len 小的爲準。兩個 slice 可指向同一底層數組,容許元素區間重疊。

package main

import (
    "fmt"
)

func main() {
    var a = []int{1, 2, 3, 4, 5}
    b := []int{100, 200}
    copy(a, b)
    fmt.Println(a, b)
}

運行結果:

[100 200 3 4 5] [100 200]
package main

import (
    "fmt"
)

func main() {
    var a = []int{1, 2, 3, 4, 5}
    b := []int{100, 200}
    copy(b, a)
    fmt.Println(a, b)
}

運行結果:

[1 2 3 4 5] [1 2]

slice中cap從新分配規律:

沒有固定長度 GO 自動給分配容量 以 2倍的方式

package main

import (
    "fmt"
)

func main() {

    s := make([]int, 0, 1)
    c := cap(s)

    for i := 0; i < 50; i++ {
        s = append(s, i)
        if n := cap(s); n > c {
            fmt.Printf("cap: %d -> %d\n", c, n)
            c = n
        }
    }

}

運行結果:

cap: 1 -> 2
cap: 2 -> 4
cap: 4 -> 8
cap: 8 -> 16
cap: 16 -> 32
cap: 32 -> 64
相關文章
相關標籤/搜索