Skip to content

3.2、Golang 切片 slice

切片:可变长度的数组

  • 自动扩容

切片声明

和数组类似,区别在于不添加长度

go
var  identifier []type

切片是引用类型,可以使用make 函数创建切片

go
// len是数组长度,也是切片的初始长度
var slice []type = make([]type, len)

// 简写
slice := make([]type, len)

// 指定容量
slice := make([]type, len, capacity)

示例

go
package main

import "fmt"

func main() {
    
    // 数组 指定长度
    var arr = [...]int{}

    // 切片 不指定长度
    var slice = []int{}

    fmt.Printf("arr: %T\n", arr)
    // arr: [0]int

    fmt.Printf("slice: %T\n", slice)
    // slice: []int

}

使用make声明

go
package main

import "fmt"

func main() {

    var slice = make([]int, 3)

    fmt.Printf("slice: %T\n", slice)
    // slice: []int

}

切片的长度和容量

go
package main

import "fmt"

func main() {

    var slice = make([]int, 3)

    // 长度
    fmt.Printf("len(slice): %v\n", len(slice))
    // len(slice): 3

    // 容量
    fmt.Printf("cap(slice): %v\n", cap(slice))
    // cap(slice): 3

}

切片初始化

直接初始化

go
s := []int{1, 2, 3, 4, 5}
fmt.Printf("s: %v\n", s)
// s: [1 2 3 4 5]

使用数组初始化

go
arr := [...]int{1, 2, 3, 4, 5}

s := arr[:]
fmt.Printf("s: %v\n", s)
// s: [1 2 3 4 5]

空切片

go
var s []int

切片操作

go
package main

import (
    "fmt"
)

func main() {
    s := []int{1, 2, 3, 4, 5}
    fmt.Printf("s: %v\n", s)
    // s: [1 2 3 4 5]

    // [0, 3)
    s1 := s[0:3]
    fmt.Printf("s1: %v\n", s1)
    // s1: [1 2 3]

    // [3, 最后)
    s2 := s[3:]
    fmt.Printf("s2: %v\n", s2)
    // s2: [4 5]

    // [开始,3)
    s3 := s[:3]
    fmt.Printf("s3: %v\n", s3)
    // s3: [1 2 3]

    // 拷贝
    s4 := s[:]
    fmt.Printf("s4: %v\n", s4)
    // s4: [1 2 3 4 5]
}

切片的遍历

for循环

go
package main

import "fmt"

func main() {
    var s = []int{1, 2, 3, 4}
    length := len(s)

    for i := 0; i < length; i++ {
        fmt.Printf("s[%v]=%v\n", i, s[i])
    }
    // s[0]=1
    // s[1]=2
    // s[2]=3
    // s[3]=4
}

for...range

go
package main

import "fmt"

func main() {
    var s = []int{1, 2, 3, 4}

    for index, value := range s {
        fmt.Printf("s[%v]=%v\n", index, value)
    }

    // s[0]=1
    // s[1]=2
    // s[2]=3
    // s[3]=4
}

切片的CURD(添加、删除、修改、查询)

切片是动态数组

添加元素

go
package main

import "fmt"

func main() {
    var s = []int{}

    // 添加单个元素
    s = append(s, 1)

    // 添加多个元素
    s = append(s, 2, 3)

    fmt.Printf("s: %v\n", s)
    // s: [1 2 3]

}

删除元素

go
package main

import "fmt"

func main() {
    var s = []int{1, 2, 3, 4, 5}

    // 删除元素3,索引为2
    // 公式:s = append(s[:index], s[index+1:]...)
    s = append(s[:2], s[3:]...)

    fmt.Printf("s: %v\n", s)
    // s: [1 2 4 5]
}

修改元素

go
package main

import (
    "fmt"
)

func main() {
    var s = []int{1, 2, 3, 4, 5}

    s[2] = 6
    fmt.Printf("s: %v\n", s)
    // s: [1 2 6 4 5]
}

查询元素

go
package main

import (
    "fmt"
)

func main() {
    var s = []int{1, 2, 3, 4, 5}

    // 查询元素的索引
    for index, value := range s {
        if value == 3 {
            fmt.Printf("index: %v\n", index)
            break
        }
    }
    // index: 2
}

切片的复制 copy

浅拷贝

go
package main

import (
    "fmt"
)

func main() {
    var s1 = []int{1, 2, 3, 4, 5}

    // 浅拷贝,地址引用,指向同一个对象
    var s2 = s1

    s2[0] = 6

    fmt.Printf("s1: %v\n", s1)
    // s1: [6 2 3 4 5]

    fmt.Printf("s2: %v\n", s2)
    // s2: [6 2 3 4 5]

}

深拷贝

go
package main

import (
    "fmt"
)

func main() {
    var s1 = []int{1, 2, 3, 4, 5}

    // copy目标容器,没有足够的空间接收数据
    var s2 = []int{}
    copy(s2, s1)

    fmt.Printf("s2: %v\n", s2)
    // s2: []

    // copy目标容器,需要预先开辟足够的内存空间
    var s3 = make([]int, len(s1))
    copy(s3, s1)
    s3[0] = 6

    // s1没有被修改
    fmt.Printf("s1: %v\n", s1)
    // s1: [1 2 3 4 5]

    // s3被修改了
    fmt.Printf("s3: %v\n", s3)
    // s3: [6 2 3 4 5]

}