• Golang切片slice


    切片slice

    • 其本身并不是数组,它指向底层的数组
    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	var s1 []int //这样的话就完成了slice的声明,如果是数组的话,必须在中括号当中必须有明确的数字或3个点
    	fmt.Println(s1)
    
    }
    
    
    • 作为变成数组的替代方案,可以关联底层数组的局部或全部
    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	var s1 []int //这样的话就完成了slice的声明,如果是数组的话,必须在中括号当中必须有明确的数字或3个点,这是个空slice
    	a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
    	fmt.Println(s1)
    	fmt.Println(a)
    	s2 := a[9]
    	s3 := a[5:10] //a[5,6,7,8,9],也可以写成a[5:]
    	fmt.Println(s2)
    	fmt.Println(s3)
    
    }
    
    • 它的值为引用类型、
    • 可以直接创建或从底层数组获取生成
    • 使用len()获取元素个数,cap()获取容量
    • 一般情况下使用make创建
    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	s1 := make([]int, 3, 10) //括号中第一个参数是类型,第二个参数是长度,第三个是容量,如果不设置容量,它就会认为默认是你的长度
    	fmt.Println(len(s1), cap(s1))
    
    }
    
    • 如果多个slice指向相同底层数组,其中一个的值改变会影响全部
    • make([]T,len,cap)
    • 其中cap可以省略,则和len的值相同
    • len表示存在的元素个数,cap表示容量

    slice与底层数组对应的关系image

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	a := [...]string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"}
    	sa := a[2:5]
    	fmt.Println(sa)
    	sb := a[3:5]
    	fmt.Println(sb)
    
    }
    

    Reslice

    • Reslice时索引以被slice的切片为准
    • 索引不可以超过slice的切片的容量cap()值
    • 索引越界不会导致底层数组的重新分配而是引发错误
    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	a := [...]string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"}
    	sa := a[2:5]
    	fmt.Println(sa)
    	//这里的sa指向的是一个连续的内存块,所以它的最大容量到这个内存块的底部
    	fmt.Println(len(sa), cap(sa))
    	sb := sa[1:3]
    	fmt.Println(sb)
    	fmt.Println(len(sb), cap(sb))
    
    }
    //PS结果:
    PS G:mygosrcmytest> go run .myfirst.go
    [c d e]
    3 9
    [d e]
    2 8
    

    Append

    • 可以在slice尾部追加元素
    • 可以将一个slice追加在另一个slice尾部
    • 如果最终长度未超过追加到slice的容量则返回原始slice
    • 如果超过追加的slice的容量则将重新分配数组并拷贝原始数据
    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	s1 := make([]int, 3, 6)
    	fmt.Printf("%v, %p 
    ", s1, s1)
    	s1 = append(s1, 1, 2, 3)
    	fmt.Printf("%v, %p 
    ", s1, s1)
    	//可以看到两次打印的内存地址是一样的,因为追加的元素没有超出原slice的容量
    }
    
    PS G:mygosrcmytest> go run .myfirst.go
    [0 0 0], 0xc04203ff50
    [0 0 0 1 2 3], 0xc04203ff50
    
    
    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	s1 := make([]int, 3, 6)
    	fmt.Printf("%v, %p 
    ", s1, s1)
    	s1 = append(s1, 1, 2, 3)
    	fmt.Printf("%v, %p 
    ", s1, s1)
    	//可以看到两次打印的内存地址是一样的,因为追加的元素没有超出原slice的容量
    	s1 = append(s1, 4, 5, 6)
    	fmt.Printf("%v %p 
    ", s1, s1)
    	//此时可以看出,最后一次的打印会重新分配内存地址
    
    }
    PS G:mygosrcmytest> go run .myfirst.go
    [0 0 0], 0xc04203ff50
    [0 0 0 1 2 3], 0xc04203ff50
    [0 0 0 1 2 3 4 5 6] 0xc04203a0c0
    
    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	a := []int{1, 2, 3, 4, 5}
    	s1 := a[2:5]
    	s2 := a[1:3]
    	fmt.Println(s1, s2)
    	s1[0] = 9
    	fmt.Println(s1, s2) //slice是指向一个底层的数组,当多个slice指向同一个底层的数组的时候,其中一个发生改变,另外的slice都会发生改变
    
    }
    PS G:mygosrcmytest> go run .myfirst.go
    [3 4 5] [2 3]
    [9 4 5] [2 9]
    
    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	a := []int{1, 2, 3, 4, 5}
    	s1 := a[2:5]
    	s2 := a[1:3]
    	fmt.Println(s1, s2)
    	s2 = append(s2, 3, 4, 5, 6, 7, 8, 9, 10) //当append的容量超过底层数组的长度时,会重新分配内存地址并拷贝原始数据
    	s1[0] = 9
    	fmt.Println(s1, s2) //slice是指向一个底层的数组,当多个slice指向同一个底层的数组的时候,其中一个发生改变,另外的slice都会发生改变
    
    }
    PS G:mygosrcmytest> go run .myfirst.go
    [3 4 5] [2 3]
    [9 4 5] [2 3 3 4 5 6 7 8 9 10]
    

    Copy

    package main
    
    import "fmt"
    
    func main() {
    	s1 := []int{1, 2, 3, 4, 5, 6}
    	s2 := []int{7, 8, 9}
    	copy(s1, s2) //将S2赋值到s1当中
    	fmt.Println(s1, s2)
    }
    PS G:mygosrcmytest> go run .mysecond.go
    [7 8 9 4 5 6] [7 8 9]
    
    package main
    
    import "fmt"
    
    func main() {
    	s1 := []int{1, 2, 3, 4, 5, 6}
    	s2 := []int{7, 8, 9}
    	s3 := s1[:] //将s1完整的拷贝给s3
    	fmt.Println(s1, s2)
    	fmt.Println(s3)
    	fmt.Printf("%p---%p 
    ", s1, s3)
    }
    
    PS G:mygosrcmytest> go run .mysecond.go
    [1 2 3 4 5 6] [7 8 9]
    [1 2 3 4 5 6]
    0xc04203ff50---0xc04203ff50
    
  • 相关阅读:
    js文字跳动效果
    js文字效果
    centos7安装Logwatch配合msmtp邮件客户端发送服务器监控分析日志
    子查询
    Hexo添加字数统计、阅读时长
    基于visual Studio2013解决C语言竞赛题之0523魔方阵
    基于visual Studio2013解决C语言竞赛题之0522和为素
    基于visual Studio2013解决C语言竞赛题之0521圆盘求和
    基于visual Studio2013解决C语言竞赛题之0520相邻元素
    基于visual Studio2013解决C语言竞赛题之0519最大值
  • 原文地址:https://www.cnblogs.com/skymyyang/p/7614864.html
Copyright © 2020-2023  润新知