go 速学 - 07 - Slice

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

目录

摘要

切片和数组的区别,创建切片,指定范围,make,遍历,reslice,append,copy

切片 Slice

概念

  • 切片本身不是数组,而是指向底层的数组,关联数组的局部或全部
  • 切片是引用类型
  • 创建切片时索引不能超过数组的大小,否则会报异常

创建 Slice

定义切片

定义时不用指定长度(指定长度或使用 “…” 表示的是数组)

//切片
var s []int
fmt.Println(s) //[]

//数组
var arr [5]int
fmt.Println(arr) //[0 0 0 0 0]

指定范围创建切片

单个索引

a := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
s1 := a[9]  //s1 10

左闭右开

s2 := a[5:10]   //s2 [6 7 8 9 10]

从指定索引开始(包含)

s3 := a[5:]     //s3 [6 7 8 9 10]

到指定索引(不包含)

s4 := a[:5]     //s4 [1 2 3 4 5]

使用 make 创建切片

格式

make([]T, len, cap)
make([]T, len)

创建时如果省略 cap,则表示和 len 相同

s5 := make([]int, 3, 10)

len()和 cap()

len() 获取元素个数,cap() 获取容量

len(s5)
cap(s5)

遍历

for i, v := range w {
    fmt.Println(i, v)
}

其中 i 为索引,如果想忽略 i 的使用可以使用占位符 “_”

//忽略值
for i := range w {
    fmt.Print(i)
}

//忽略索引
for _, v := range w {
    fmt.Print(v)
}

Reslice

即指向 Slice 的 Slice

Reslice 时的索引以被 slice 的切片为准

w := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}
fmt.Println("w", w)   //w [97 98 99 100 101 102 103 104 105 106 107]
wa := w[2:5]        //wa [99 100 101]
wb := wa[3:5]       //wb [102 103]

Append

概念

  • 用于在 slice 尾部追加元素
  • 如果最终长度未超过追加到 slice 的容量则返回原始 slice
  • 如果超过以追加到的 slice 的容量则将重新分配数组并拷贝原始数据
  • 当两个 slice 指向同一个数组时,如果其中一个 slice 超过了容量,那么再改变它不会影响到另一个 slice,因为此 slice 其实已经指向新的内存空间了

使用

语法

resultSlice:=append(originalSlice, ele1, ele2, ele3...)

n1 := make([]int, 3, 6)
fmt.Println("n1", n1) //n1 [0 0 0]

n2 := append(n1, 1, 2)
fmt.Println("n1", n1)                   //n1 [0 0 0]
fmt.Println("n2", n2, len(n2), cap(n2)) //n2 [0 0 0 1 2]    5   6

//没有超过原slice 的容量,会影响其它slice
n3 := append(n1, 3)
fmt.Println("n1", n1) //n1 [0 0 0]
fmt.Println("n2", n2) //n2 [0 0 0 3 2]
fmt.Println("n3", n3) //n3 [0 0 0 3]

n4 := append(n1, 4, 5, 6)
fmt.Println("n1", n1) //n1 [0 0 0]
fmt.Println("n2", n2) //n2 [0 0 0 4 5]
fmt.Println("n3", n3) //n3 [0 0 0 4]
fmt.Println("n4", n4) //n4 [0 0 0 4 5 6]

//超过原slice 的容量,指向新地址,不会影响其它slice
n5 := append(n1, 7, 8, 9, 10)
fmt.Println("n1", n1) //n1 [0 0 0]
fmt.Println("n2", n2) //n2 [0 0 0 4 5]
fmt.Println("n3", n3) //n3 [0 0 0 4]
fmt.Println("n4", n4) //n4 [0 0 0 4 5 6]
fmt.Println("n5", n5) //n5 [0 0 0 7 8 9 10]

Copy

语法

copy(to,from)

a := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
c1 := a[2:5]
c2 := a[5:8]
fmt.Println("c1", c1) //c1 [3 4 5]
fmt.Println("c2", c2) //c2 [6 7 8]

copy(c1, c2)
fmt.Println("c1", c1) //c1 [6 7 8]
fmt.Println("c2", c2) //c2 [6 7 8]

目标切片的容量可以小于源切片的容量

c3 := a[2:3]
c4 := a[3:9]
fmt.Println("c3", c3) //c3 [6]
fmt.Println("c4", c4) //c4 [7 8 6 7 8 9]

copy(c3, c4)
fmt.Println("c3", c3) //c3 [7]
fmt.Println("c4", c4) //c4 [7 8 6 7 8 9]

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

本文来自:CSDN博客

感谢作者:mrseasons

查看原文:go 速学 - 07 - Slice

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

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