Go语言切片

概念

Go 语言切片是对数组的抽象。
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

package main

import "fmt"

func main() {
    // 定义并初始化
    s := []int{1,2,3}
    fmt.Println(s)
    // 切片的定义
    var names []string
    // nil 类似于其他语言中的空
    fmt.Println(names == nil) //true
    // 初始化
    names = []string{"jack", "tom", "rose", "jerry"}
    fmt.Println(names)
    // 长度和容量
    fmt.Println(len(names))
    fmt.Println(cap(names))
    // 由数组得到切片
    a1 := [...]int{1, 2, 3, 4, 5}
    a2 := a1[1:3]
    a3 := a1[:3]
    a4 := a1[1:]
    a5 := a1[:]
    fmt.Println(a1, a2)
    // 由数组得到的切片的长度和容量
    fmt.Println(len(a2), cap(a2)) // 2,4
    fmt.Println(len(a3), cap(a3)) //3,5
    fmt.Println(len(a4), cap(a4)) //4,4
    fmt.Println(len(a5), cap(a5)) // 5,5

}

使用make函数创建切片

package main 

import "fmt"

func main(){
    // 可以使用make函数指定切片的容量和长度
    s := make([] int, 5,10)
    fmt.Println(s,len(s),cap(s))
}

切片的本质

切片的本质就是对底层数组的封装,它包含了三个信息:底层数组的指针、切片的长度(len)和切片的容量(cap)。切片之间是不能比较的,我们不能使用==操作符来判断两个切片是否含有全部相等元素。 切片唯一合法的比较操作是和nil比较。 一个nil值的切片并没有底层数组,一个nil值的切片的长度和容量都是0。但是我们不能说一个长度和容量都是0的切片一定是nil

package main

import "fmt"

func main() {
    // s1 := make([]int, 0)
    // s2 := []int{}
    // slice can only be compared to nil
    // fmt.Println(s1 == s2)
    // fmt.Println(s1 == nil) //false
    var s1[] int
    fmt.Println(s1 == nil) //true
}

切片的拷贝赋值

package main

import "fmt"

func main(){
    s1 := []int{1,2,3}
    s2 := s1  //指向同一块内存空间
    s1[1] = 111
    fmt.Println(s1,s2)
        // 还可以使用copy函数来赋值切片
        a := []int{1, 2, 3, 4, 5}
    c := make([]int, 5, 5)
        // c:数据来源切片和目标切片
    copy(c, a)     //使用copy()函数将切片a中的元素复制到切片c
    fmt.Println(a) //[1 2 3 4 5]
    fmt.Println(c) //[1 2 3 4 5]
    c[0] = 1000
    fmt.Println(a) //[1 2 3 4 5]
    fmt.Println(c) //[1000 2 3 4 5]
}

切片的遍历

func main() {
    s := []int{1, 3, 5}

    for i := 0; i < len(s); i++ {
        fmt.Println(i, s[i])
    }

    for index, value := range s {
        fmt.Println(index, value)
    }
}

切片的新增、删除和扩容

Go语言的内建函数append()可以为切片动态添加元素,每个切片会指向一个底层数组,这个数组的容量够用就添加新增元素。当底层数组不能容纳新增的元素时,切片就会自动按照一定的策略进行“扩容”,此时该切片指向的底层数组就会更换。“扩容”操作往往发生在append()函数调用时,所以我们通常都需要用原变量接收append函数的返回值。

package main

import "fmt"

func main(){
    s1 := make([]int,2,3)
    s1[0] = 0
    s1[1] = 1
    // s1[2] = 2 //index out of range [2] with length 2
    // 使用append函数向切片中增加 如果长度、容量不够会自动扩容
        // 使用append函数,必须使用元切片接受返回值
    s1 = append(s1,2)
    fmt.Println(s1)
        // go语言中没有提供切片的删除方法,我们可以使用append来模拟切片的删除操作
      // 从切片中删除元素
    a := []int{30, 31, 32, 33, 34, 35, 36, 37}
    // 要删除索引为2的元素
    a = append(a[:2], a[3:]...)
    fmt.Println(a) //[30 31 33 34 35 36 37]

        ss1 := []int{1,2,3}
    ss2 := []int{11,22}
    // ss2... 将切片展开
    ss1 = append(ss1,ss2...)
    fmt.Printf("%v,%d,%d",ss1,len(ss1),cap(ss1))
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容