【Golang系列】-切片

2022-03-10

切片

数组是固定长度,有时候还是不好用,比如申请的长度太大,浪费内存
go语言的切片,可以理解为可变长度的数组,切片是一个拥有相同类型元素的可变长度的序列

语法:

声明一个切片和声明 一个数组类似,只要不添加长度就可以了

var identifier [] type

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

var slice1 []type = make([]type,len)

//可以简单写

slice := make([]type,len)

还可以指定容量,其中capacity为可选参数

make([]T,length,len)

这里len是数组的长度也是切片的初始长度

示例:
package main

import "fmt"

func f() {
    var s1 = []int{1, 2, 3, 4, 5, 6}
    s2 := s1[0:3]
    fmt.Println(s2)
}


func main() {
    f()
}

切片的初始化:

切片的初始化方法很多,可直接初始化,也可以使用数组初始化
直接初始化

package main
import "fmt"
func main() {
    s := []int{1, 2, 3}
    fmt.Println(s)
}
切片如何切分
package main

import "fmt"

func f() {
    var s1 = []int{1, 2, 3, 4, 5, 6}
    s2 := s1[0:3]
    fmt.Println(s2)
    s3 := s1[3:]
    fmt.Println(s3)
    s4 := s1[2:5]
    fmt.Println(s4)
    s5 := s1[:]
    fmt.Println(s5)
}

func main() {
    f()
}

结果:

[1 2 3]
[4 5 6]
[3 4 5]
[1 2 3 4 5 6]

使用数组初始化
package main

import "fmt"

func f() {
    arr := [...]int{1, 2, 3}
    s1 := arr[:]
    fmt.Println(s1)
}


func main() {
    f()
}

使用数组的部分元素初始化

切片的底层就是一个数组,所以我们可以基于数组通过切片表达式得到切片,切片表达式中的low和high表示一个索引范围(左包含,右不包含)得到的切片长度=higt-low容量等于得到的切片底层数组的容量

package main

import "fmt"

func f() {
    arr := [...]int{1, 2, 3, 4, 5, 6}
    s1 := arr[2:5]
    fmt.Println(s1)
    s2 := arr[2:]
    fmt.Println(s2)
    s3 := arr[:3]
    fmt.Println(s3)
}

func main() {
    f()
}

空切片nil

一个切片在末初始化之前默认为nil,长度是0,容量是0

[Running] go run "/Users/lihui/Desktop/gocode/src/chapter05/dome01.go"
[]
true
0 0
[Done] exited with code=0 in 0.89 seconds

切片的遍历

切片的遍历跟数组的遍历很相似,可以使用for循环索引遍历,也可以使用for range循环

for循环
package main

import "fmt"

func main() {
    s1 := []int{1, 2, 3, 4, 5, 6}
    for i := 0; i < len(s1); i++ {
        fmt.Println(s1[i])
    }
}

for range遍历:
package main

import "fmt"

func main() {
    s1 := []int{1, 2, 3, 4, 5, 6}
    for i, v := range s1 {
        fmt.Println(i, v)
    }
}

切片的元素添加删除复制

切片是一个动态数组,可以使用append()函数添加元素,没有删除切片的专们的方法,可以使用切片本身的特殊性来删除切片,由于是引用类型,通过赋值,会修改原有的内容,go提供copy()函数来拷贝切片

添加元素
package main

import "fmt"

func main() {
    s1 := []int{1, 2, 3}
    s1 = append(s1, 7, 8)//添加多个元素
    fmt.Println(s1)
    s2 := []int{4, 5, 9}
    s2 = append(s2, s1...)//添加另外一个切片
    fmt.Println(s2)
}

拷贝切片
package main

import "fmt"

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

    s2[0] = 100
    fmt.Println(s1)
    fmt.Println(s2)
    fmt.Println("====copy函数====")

    s3 := make([]int, 6)
    copy(s3, s1)
    s1[0] = 1

    fmt.Println(s1)
    fmt.Println(s3)
}

结果:

[Running] go run "/Users/lihui/Desktop/gocode/src/chapter05/dome02.go"
[1 2 3 4 5 6]
=========
[100 2 3 4 5 6]
[100 2 3 4 5 6]
====copy函数====
[1 2 3 4 5 6]
[100 2 3 4 5 6]

[Done] exited with code=0 in 0.379 seconds

从结果来看,我们看到赋值的情况下,原来的变量被修改了,使用copy函数,原来的变量没有被修改。