• Go语言入门【6】切片


    切片

    在go语言中,切片是对数组的抽象,数组在声明时指定了长度之后就不可再进行改变,在特定场景下数组就不适用,所以就有了切片类型,切片就是“动态数组”,和数组相比,切片的长度是不固定的,可以在切片后面追加元素,长度自动扩容。

    切片定义

    定义切片和定义数组很像,区别就是定义一个切片不需要指定长度。

    var 切片名 []类型
    
    • 1

    切片还可以使用make函数定义。

    make([]T, length, capacity)
    
    • 1

    make函数有三个参数:

    1. 第一个参数为切片类型,可以是[]int,[]string,[]float32等。
    2. 第二个参数为切片初始长度。
    3. 第三个为切片容量,该参数为可选参数。

    切片初始化

    一个切片在初始化之前为空切片(nil),长度为0,可以在声明切片时直接初始化切片,如下表示声明一个int切片,初始化值为{1, 2, 3}

    s :=[] int {1,2,3 }
    
    • 1

    初始化为数组的引用,假设有一个数组arr,在初始化为数组的引用时,通过开始索引和结束索引控制初始化的切片大小和切片内元素个数。

    s := arr[startIndex:endIndex]	// 从 startIndex 到 endIndex - 1 初始化为一个切片
    s := arr[startIndex:]			// 从 startIndex 到 数组结尾 初始化为一个切片
    s := arr[:endIndex]				// 从 数组开始 到 endIndex - 1 初始化为一个切片
    s := arr[:]						// 从 数组开始 到 数组结尾 初始化为一个切片(整个数组)
    
    • 1
    • 2
    • 3
    • 4

    代码示例:

    package main
    
    import "fmt"
    
    func main() {
    	arr := [5]int{1, 2, 3, 4, 5}
    	s1 := arr[:]
    	s2 := arr[2:]
    	s3 := arr[:3]
    	s4 := arr[1:4]
    	fmt.Println(s1)
    	fmt.Println(s2)
    	fmt.Println(s3)
    	fmt.Println(s4)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    运行结果:

    运行结果

    append和copy

    append表示在一个切片的末尾追加元素。

    copy表示复制一个切片里面的元素到另一个切片。

    代码示例:

    package main
    
    import "fmt"
    
    func main() {
    	s := []int{1,2,3}
    	fmt.Println("切片s:",s)
    	s = append(s, 4)					// 添加一个元素4到切片s中
    	fmt.Println("切片s:",s)
    	s1 := make([]int, 4)
    	copy(s1, s)											// 将切片s的内容拷贝到切片s1中
    	fmt.Println("切片s1:",s1)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    运行结果:

    运行结果

    切片截取

    切片截取使用中括号[],通过指定需要截取的开始索引和结束索引。

    代码示例:

    package main
    
    import "fmt"
    
    func main() {
    	s := []int{1,2,3,4,5}
    	fmt.Println("完整切片:", s)
    	fmt.Println("s[1:3]:", s[1:3])			// 截取索引1(包含)到索引3(不包含)
    	fmt.Println("s[:4]:", s[:4])			// 默认开始索引为0
    	fmt.Println("s[2:]:", s[2:])			// 默认结束索引为len
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运行结果:

    运行结果

    len和cap

    长度和容量区别:

    • 长度:长度表示切片中实际存储的元素个数
    • 容量:容量表示切片底层使用的数组的大小

    当定义一个切片时,如果没有通过make方法指定cap,则底层会申请一个和切片长度一样的数组,这个数组的大小就是cap,当使用append朝切片中追加元素时,如果追加元素后新的len小于cap,则底层数组不会改变,当新的len大于cap时,底层就会重新申请一个数组,且数组的长度为cap * 2,然后将之前数组的元素全部复制到新数组中。

    代码示例:

    package main
    
    import "fmt"
    
    func main() {
    	s := make([]int, 3)
    	fmt.Printf("len:%d, cap:%d \n", len(s), cap(s))		// 此时len=3,cap=3
    
    	s = append(s, 1)
    	fmt.Printf("len:%d, cap:%d \n", len(s), cap(s))		// append一个元素,len=4,大于cap,所以底层数组扩容,cap=6
    
    	s = append(s, 1)
    	fmt.Printf("len:%d, cap:%d \n", len(s), cap(s))		// append一个元素,len=5,小于cap,底层数组不变,cap=6
    
    	s = append(s, 1)
    	fmt.Printf("len:%d, cap:%d \n", len(s), cap(s))		// append一个元素,len=6,小于cap,底层数组不变,cap=6
    
    	s = append(s, 1)
    	fmt.Printf("len:%d, cap:%d \n", len(s), cap(s))		// append一个元素,len=7,大于cap,所以底层数组扩容,cap=12
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    运行结果:

    运行结果

    关注专栏,持续更新

  • 相关阅读:
    html和css复习1
    Oracle Forms 编译时ORA-01445和 FRM-40501错误
    如虎添翼?微软OneNote迎来新利器
    力扣第45题 跳跃游戏II c++ 贪心算法
    大数据架构设计(四十五)
    C. Orac and LCM(gcd与lcm的性质)
    正则表达式
    餐厅点餐系统的设计
    Maven历史版本下载
    2022/8/4 树上差分+线段树
  • 原文地址:https://blog.csdn.net/qq_41286145/article/details/127897687