• Golang Slice切片


    1. 切片的定义和初始化

    • 切片是基于数组类型的封装,非常灵活,可以自动扩容
    • 切片是真正意义上的动态数组,而且是一个引用类型,切片指向一个底层数组

    定义切片

    var 切片名[] 切片类型
    

    创建切片方式

    package main
    
    import "fmt"
    
    func main() {
    	// 1. 声明切片
    	var s1 []int
    	if s1 == nil { // 只声明没有初始化,所以是nil
    		fmt.Println("为空")
    	} else {
    		fmt.Println("不为空")
    	}
    
    	// 2. := 自动推导
    	s2 := []int{}
    
    	// 3. make(切片类型, 长度, 容量)
    	// 容量是可选的
    	var s3 []int = make([]int, 0)
    
    	fmt.Println(s1, s2, s3)
    
    	// 4. 初始化赋值
    	var s4 []int = make([]int, 0, 0)
    	fmt.Println(s4)
    
    	s5 := []int{1,2,3}
    	fmt.Println(s5)
    
    	// 5. 从数组切片
    	arr := [5]int{1,2,3,4,5}
    	var s6 []int
    	s6 = arr[1:4]
    	fmt.Println(s6)
    }
    

    2. 切片操作

    操作 含义
    s[n] 切片 s 中索引位置为 n 的项
    s[:] 从切片 s 的索引位置 0 到 len(s)-1 处所获得的切片
    s[low:] 从切片 s 的索引位置 low 到 len(s)-1 处所获得的切片
    s[:high] 从切片 s 的索引位置 0 到 high 处所获得的切片,len=high
    s[low:high] 从切片 s 的索引位置 low 到 high 处所获得的切片,len=high-low
    s[low: high:max] 从切片 s 的索引位置 low 到 high 处所获得的切片,len=high-low, cap=max-low
    len(s) 切片 s 的长度,总是<=cap()
    cap(s) 切片 s 的容量,总是>=len(s)
    package main
    
    import "fmt"
    
    func op01() {
    	// 定义数组
    	array := [...]int{1, 2, 3, 4, 5, 6, 7, 9, 0}
    
    	// 切片
    	fmt.Println(array[:])
    	fmt.Println(array[1:5])
    	fmt.Println(array[:6])
    	fmt.Println(array[2:])
    	fmt.Println(array[2])
    }
    
    func op02() {
    	s1 := make([]int, 3, 5)
    	fmt.Printf("s1: %v, len: %d, cap: %d", s1, len(s1), cap(s1))
    }
    
    func op03() {
    	// 初始化一个数组
    	arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8}
    
    	s1 := arr[2:5]
    	fmt.Println(s1)
    
    	// 可以向后扩展,默认是不扩展,不可以向前扩展
    	s2 := s1[2:7]
    	fmt.Println(s2)
    }
    
    func main() {
    	op01()
    	op02()
    	op03()
    }
    

    3. append()函数

    向 slice 尾部添加数据,返回新的 slice 对象

    package main
    
    import "fmt"
    
    func main() {
    	// 空切片
    	var s001 []int
    
    	s001 = append(s001, 1)
    	s001 = append(s001, 3)
    	s001 = append(s001, 6)
    	fmt.Println(s001)
    
    	// 初始化内存的切片
    	s002 := make([]int, 5)
    	s002 = append(s002, 5, 8, 9)
    	fmt.Println(s002)
    
    	// 初始化默认值的切片
    	s003 := []int{1, 3, 6}
    	s003 = append(s003, 4, 99, 2)
    	fmt.Println(s003)
    }
    
    package main
    
    import "fmt"
    
    func main() {
    	// 初始化一个数组
    	arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8}
    
    	// 初始化一个从数组切片的slice
    	s1 := arr[2:]
    	fmt.Println(arr)
    	fmt.Println(s1)
    
    	// 修改s1切片的值
    	// view(视图)操作,会修改原数组的值
    	s1[0] = 100
    	fmt.Println(s1)
    	fmt.Println(arr)
    }
    
    // 输出结果
    // [0 1 2 3 4 5 6 7 8]
    // [2 3 4 5 6 7 8]
    // [100 3 4 5 6 7 8]
    // [0 1 100 3 4 5 6 7 8]
    
    package main
    
    import "fmt"
    
    func main() {
    	arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
    	s1 := arr[2:6]
    	fmt.Println(s1)
    	s2 := s1[3:5]
    	fmt.Println(s2)
    
    	// 映射到底层是覆盖操作
    	s3 := append(s2, 10)
    	fmt.Println(s3)
    	fmt.Println(arr)
    	fmt.Println()
    
    	// 底层去自动扩容, 此时打印的是原数组
    	s4 := append(s3, 11)
    	fmt.Println(s4)
    	fmt.Println(arr)
    
    	s5 := append(s4, 12)
    	fmt.Println(s5)
    	fmt.Println(arr)
    }
    
    package main
    
    import "fmt"
    
    func main() {
    	var a []int = []int{1, 2, 3}
    	var b []int = []int{4, 5, 6}
    
    	a = append(a, 7, 8)
    	fmt.Println(a)
    
    	// append无法直接添加一个切片,需要使用...将切片打散
    	a = append(a, b...)
    	fmt.Println(a)
    }
    

    4. copy()函数

    在两个 slice 间复制数据,两个 slice 可指向同一底层数组

    package main
    
    import "fmt"
    
    func main() {
    	arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
    	s1 := arr[8:] // [8 9 10 11 12 13 14]
    	s2 := arr[:5] // [0 1 2 3 4]
    	fmt.Println(s1, s2)
    
    	// 从左侧开始覆盖
    	copy(s1, s2)
    	fmt.Println(s1, s2) // [0 1 2 3 4 13 14] [0 1 2 3 4]
    	fmt.Println(arr)    // [0 1 2 3 4 5 6 7 0 1 2 3 4 13 14]
    }
    

    5. 切片扩容机制

    用 make()创建切片,可以指定容量,当容量存储到上限,底层会自动扩容

    package main
    
    import "fmt"
    
    func main() {
    	var a []int = make([]int, 5, 10)
    	fmt.Printf("a=%v, len=%d, cap=%d
    ", a, len(a), cap(a))
    
    	a[0] = 10
    	a[1] = 20
    	fmt.Printf("a=%v, len=%d, cap=%d
    ", a, len(a), cap(a))
    
    	a = append(a, 30)
    	fmt.Printf("a=%v, len=%d, cap=%d
    ", a, len(a), cap(a))
    
    	for i := 0; i <= 8; i++ {
    		a = append(a, i)
    		fmt.Printf("for a=%v, len=%d, cap=%d
    ", a, len(a), cap(a))
    
    	}
    	fmt.Printf("a=%v, len=%d, cap=%d
    ", a, len(a), cap(a))
    }
    

    切片再切片

    package main
    
    import "fmt"
    
    func main() {
    	a := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    	fmt.Printf("a=%v, len=%d, cap=%d
    ", a, len(a), cap(a))
    	b := a[1:3]
    	fmt.Printf("b=%v, len=%d, cap=%d
    ", b, len(b), cap(b))
    
    	// 切片再切片
    	b = b[:cap(b)]
    	fmt.Printf("b=%v, len=%d, cap=%d
    ", b, len(b), cap(b))
    }
    

    空切片的扩容机制

    package main
    
    import "fmt"
    
    func main() {
    	var a []int
    	fmt.Printf("a=%v, len=%d, cap=%d
    ", a, len(a), cap(a))
    
    	a = append(a, 10)
    	fmt.Printf("a=%v, len=%d, cap=%d
    ", a, len(a), cap(a))
    	a = append(a, 20)
    	fmt.Printf("a=%v, len=%d, cap=%d
    ", a, len(a), cap(a))
    	a = append(a, 30)
    	fmt.Printf("a=%v, len=%d, cap=%d
    ", a, len(a), cap(a))
    	a = append(a, 40)
    	fmt.Printf("a=%v, len=%d, cap=%d
    ", a, len(a), cap(a))
    	a = append(a, 50)
    	fmt.Printf("a=%v, len=%d, cap=%d
    ", a, len(a), cap(a))
    	a = append(a, 60)
    	fmt.Printf("a=%v, len=%d, cap=%d
    ", a, len(a), cap(a))
    }
    
  • 相关阅读:
    Spark之 SparkSql整合hive
    Spark之 使用SparkSql操作Hive的Scala程序实现
    Spark之 RDD转换成DataFrame的Scala实现
    Spark之 SparkSql、DataFrame、DataSet介绍
    Spark之 RDD
    Spark scala和java的api使用
    设计模式之四观察者模式
    设计模式之三静态代理模式
    设计模式之二装饰者模式
    设计思想之二面向接口编程
  • 原文地址:https://www.cnblogs.com/zhichaoma/p/12510015.html
Copyright © 2020-2023  润新知