3.Golang 切片(重点,哪里不对,请多多指点)

三人行大道 · · 889 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

切片拥有自己的长度和容量,
我们可以通过使用内置的len()函数求长度,使用内置的cap()函数求切片的容量

切片在python是很常见的,而且很简单,但是在Golang中就不是那么的好玩了

切片(Slice)是一个拥有相同类型元素的可变长度的序列。它是基于数组类型做的一层封装。非常灵活,支持自动扩容。

切片属于引用类型,它的内部结构包含地址、长度和容量。切片一般用于快速地操作一块数据集合

1.切片的定义
2.切片初始化
3.由数组得到切片
4.make()函数构造切片
5.append 为切片追加元素
6.copy元素
7.删除元素

切片的定义

var name []T 
name表示变量名
T表示切片中的元素类型
切片类型的写法是 []T ,  T 是切片元素的类型。和数组不同的是,切片类型并没有给定固定的长度。

// 定义切片
    var s []int     // 定义一个存放int类型元素的切片
    var s2 []string // 定义一个存放 string类型元素的切片
    fmt.Println(s, s2)
    fmt.Println(s == nil)
    fmt.Println(s2 == nil)
    // nil 相当于空的意思


初始化


s = []int{1, 2, 3}
s2 = []string{"黄河", "张江高科", "平顶山"}
s3 := []int{1,2,3}
fmt.Println(s, s2)

切片的长度和容量,切片的长度就是它元素的个数,
(切片的容量底层数组从切片的第一个元素到最后一个元素的数量) 这句最后去证实一下
切片是引用类型,都指向底层的一个数组
len(s3),cap(s3)

由数组得到切片

切片,基于一个数组的切割,左包含右不包含(左闭右开)
a1 := [...]int{1, 3, 5, 7, 9, 11, 13}
s3 := a1[0:4] //1,3,5,7 切片,基于一个数组的切割,左包含右不包含(左闭右开)
fmt.Println(s3)
s4 := a1[1:6] //3, 5, 7, 9, 11, 13
fmt.Println(s4)

s5 := a1[:4]
s6 := a1[3:] // [3:len(a1)]
s7 := a1[:]  // [3:len(a1)]
fmt.Println(s5, s6, s7)

切片的容量是指底层数组的容量



make 构造切片

使用make()函数构造切片
格式 make([]T, size, cap)
T:切片的元素类型
size:切片中元素的数量
cap:切片的容量


    // 表示长度是5,容量是10
    s1 := make([]int, 5, 10)
    fmt.Printf("s1=%v,len(s1)=%d, cap(s1)=%d\n", s1, len(s1), cap(s1))

    // 切片的赋值,切片是引用类型,(切片是不保存值的,值都是底层数组保存的)
    s3 := []int{1, 3, 5}
    s4 := s3 // s3和s4 都指向了同一个底层数组,如果改变了其中的值,对应的s3,s4的值也会改变的
    fmt.Println(s4)
    s3[0] = 1000
    fmt.Println(s3, s4)

    // 切片的遍历
    // 1.索引遍历
    for i := 0; i < len(s3); i++ {
        fmt.Println(s3[i])
    }

    // 2 for range循环
    for index, value := range s3 {
        fmt.Println(index, value)
    }



1.(重点)
    切片的本质,就是一个框,框住了一块连续的内存,只能保存 相同类型的
    属于引用类型 真正的数据都是保存在底层数组里的
2.切片不能直接比较
    切片之间是不能比较的,我们不能直接使用 == 操作符来判断两个切片是否含有全部相等元素,
    切片唯一合法的比较操作是和 nil 比较。
    一个nil 值的切片并没有底层数组,一个nil 值的切片的长度,和容量都是0,
    但是我们不能说一个长度和容量都是0 的切片一定是 nil

    var s1 []int
    s2 := []int{}
    s3 := make([]int,0)

    所以要判断一个切片 是否是空,要用len(s) == 0 来判断,不应该使用,s == nil来判断

append 为切片追加元素

var stu = []int{}
fmt.Println(stu)
fmt.Printf("%T\n", stu)
s1 := []string{"北京", "上海", "皇甫村"}
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))

s1[3] = "广州"  index out of range 
错误写法,会导致编译错误,索引越界
调用内置append 函数必须用原来的切片变量接收返回值

s1 = append(s1, "郑州") 
在尾部追加
append追加元素,原来的底层数组放不下的时候,
Go底层就会把底层数组换一个,必须用(原来的)变量接收append的返回值


fmt.Println(s1)
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))

ss := []string{"新乡", "卫辉", "卫河"}

s1 = append(s1, ss...)  ... 表示拆开,也就是说 把新乡,卫辉,卫河 单独拿出来
fmt.Println(s1, len(s1), cap(s1))

千万要注意容量变化

copy

a1 := []int{1, 3, 5}

a2 := a1 // 切片是引用类型,这里我们可以认为是a1,a2,同时指向同一片内存地址

var a3 []int //nil (没有理解)

var a3 = make([]int, 3, 3) //长度3,容量3

copy(a3, a1) //copy 就是浅copy
fmt.Println(a1, a2, a3)
a1[0] = 100
fmt.Println(a1, a2, a3)

// 从切片中删除元素
a := []int{30, 31, 32, 33, 34, 35, 36, 37}
// 要删除索引为2的元素
a = append(a[:2], a[3:]...)
fmt.Println(len(a), cap(a), a) //[30 31 33 34 35 36 37]

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:三人行大道

查看原文:3.Golang 切片(重点,哪里不对,请多多指点)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

889 次点击  
加入收藏 微博
上一篇:leetcode_455
下一篇:leetcode_453
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传