golang学习笔记 ---slice
- 指向底层数组的指针
- slice目前使用到的底层数组的元素个数,即长度
- 底层数组的最大长度,即容量
因此当我们定义一个切片变量,s := make([]int, 5, 10),即为指向了一个最大长度为10的底层数组,目前切片s使用到的长度为5。
基于slice的定义,在使用slice时,有以下几点注意事项:
- 当从左边界有截断时,会改变新切片容量大小
- 左边界默认0,最小为0;右边界默认slice的长度,最大为slice的容量
- 当然,因为指向同一个底层数组,对新slice的操作会影响到原来的slice
- package main
- import (
- "fmt"
- )
- func main() {
- a := make([]int, 5, 10)
- b := a[:3]
- //b len: 3 cap: 10
- fmt.Println("b-- ", "len:", len(b), " ,cap:", cap(b))
- //当从左边界有截断时 会改变新切片容量大小
- c := a[2:4]
- //c len: 2 cap: 8
- fmt.Println("c-- ", "len:", len(c), " ,cap:", cap(c))
- //左边界默认0 最小为0 | 右边界默认slice的长度 最大为slice的容量
- d := a[:cap(a)]
- //d len: 10 cap: 10
- fmt.Println("d-- ", "len:", len(d), " ,cap:", cap(d))
- }
输出:
- b-- len: 3 ,cap: 10
- c-- len: 2 ,cap: 8
- d-- len: 10 ,cap: 10
2.slice的赋值及函数间传递
- a := []int{1, 2, 3, 4, 5}
- b := a
- package main
- import (
- "fmt"
- )
- func main() {
- a := []int{1, 2, 3, 4, 5}
- b := a
- //对b进行操作会影响到a
- b[0] = 10
- // 10 2 3 4 5
- fmt.Println(a)
- }
输出:
- [10 2 3 4 5]
如上所示,则a, b指向同一个底层数组,且长度及容量因素相同,对b进行的操作会影响到a。
切片作为函数参数示例:
- package main
- import (
- "fmt"
- )
- func modifySlice(s []int) {
- s[0] = 10
- }
- func main() {
- a := []int{1, 2, 3, 4, 5}
- modifySlice(a)
- //[10 2 3 4 5]
- fmt.Println(a)
- }
输出:
- [10 2 3 4 5]
如上所示,将slice作为参数在函数间传递的时候是值传递,产生了一个新的slice,只不过新的slice仍然指向原来的底层数组,所以通过新的slice也能改变原来的slice的值
- package main
- import (
- "fmt"
- )
- func modifySlice(s []int) {
- s = []int{10, 20, 30, 40, 50}
s[0] = -1- }
- func main() {
- a := []int{1, 2, 3, 4, 5}
- modifySlice(a)
- //[1 2 3 4 5]
- fmt.Println(a)
- }
如上所示,在调用函数的内部,将s整体赋值一个新的slice,并不会改变a的值,因为modifySlice函数内对s重新的整体赋值,让s指向了一个新的底层数组,而不是传递进来之前的a指向的那个数组,之后s的任何操作都不会影响到a了。
3.slice的append操作
- func append(s []T, x ...T) []T
- package main
- import (
- "fmt"
- )
- func main() {
- a := make([]int, 2, 4)
- fmt.Println("initialize.....")
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- //通常append操作都是将返回值赋值给自己,
- //此处为了方便说明,没有这样做
- //改变b的前2个元素值 会影响到a
- a[0] = 99
- fmt.Println("赋值之后.....")
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- fmt.Println("Append之后.....")
- b := append(a, 2)
- b[0] = 1
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- fmt.Println("b:", b, " &b[0]:", &b[0], " len:", len(b), " cap:", cap(b))
- a = append(a, 3)
- fmt.Println("a Append之后.....")
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- fmt.Println("b:", b, " &b[0]:", &b[0], " len:", len(b), " cap:", cap(b))
- a = append(a, 4)
- a = append(a, 5)
- fmt.Println("a 再次Append之后.....")
- //a 扩容了,指向不同的底层数组
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- //a的扩容没有影响到b,b还是指向原来的底层数组
- fmt.Println("b:", b, " &b[0]:", &b[0], " len:", len(b), " cap:", cap(b))
- }
输出:
- initialize.....
- a: [0 0] &a[0]: 0xc0000105a0 len: 2 cap: 4
- 赋值之后.....
- a: [99 0] &a[0]: 0xc0000105a0 len: 2 cap: 4
- Append之后.....
- a: [1 0] &a[0]: 0xc0000105a0 len: 2 cap: 4
- b: [1 0 2] &b[0]: 0xc0000105a0 len: 3 cap: 4
- a Append之后.....
- a: [1 0 3] &a[0]: 0xc0000105a0 len: 3 cap: 4
- b: [1 0 3] &b[0]: 0xc0000105a0 len: 3 cap: 4
- a 再次Append之后.....
- a: [1 0 3 4 5] &a[0]: 0xc000014240 len: 5 cap: 8
- b: [1 0 3] &b[0]: 0xc0000105a0 len: 3 cap: 4
- a 再次Append之后,a 扩容了,指向不同的底层数组,a的扩容没有影响到b,b还是指向原来的底层数组
- package main
- import (
- "fmt"
- )
- func main() {
- a := make([]int, 2, 4)
- a[0] = 10
- a[1] = 20
- //a: [10 20] &a[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- //进行append操作
- b := append(a[:1], 1)
- //a: [10 1] &a[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- //b: [10 1] &b[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("b:", b, " &b[0]:", &b[0], " len:", len(b), " cap:", cap(b))
- }
输出:
- a: [10 20] &a[0]: 0xc0000105a0 len: 2 cap: 4
- a: [10 1] &a[0]: 0xc0000105a0 len: 2 cap: 4
- b: [10 1] &b[0]: 0xc0000105a0 len: 2 cap: 4
- package main
- import (
- "fmt"
- )
- func main() {
- a := make([]int, 2, 4)
- a[0] = 10
- a[1] = 20
- //a: [10 20] &a[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- //进行append操作
- //b := append(a[:1], 1)
- c := a[:1]
- fmt.Println("c:", c, " &c[0]:", &c[0], " len:", len(c), " cap:", cap(c))
- b := append(c, 1)
- //a: [10 1] &a[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- //b: [10 1] &b[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("b:", b, " &b[0]:", &b[0], " len:", len(b), " cap:", cap(b))
- }
输出:
- a: [10 20] &a[0]: 0xc000072140 len: 2 cap: 4
- c: [10] &c[0]: 0xc000072140 len: 1 cap: 4
- a: [10 1] &a[0]: 0xc000072140 len: 2 cap: 4
- b: [10 1] &b[0]: 0xc000072140 len: 2 cap: 4
- package main
- import (
- "fmt"
- )
- func main() {
- a := make([]int, 2, 4)
- a[0] = 10
- a[1] = 20
- //a: [10 20] &a[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- //进行append操作
- //append是在第一个元素后开始追加,所以要超过容量,至少要追加4个,而不是之前例子的3个
- b := append(a[:1], 1, 2, 3, 4)
- //a: [10 20] &a[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- //b: [10 1 2 3 4] &b[0]: 0x10454020 len: 5 cap: 8
- fmt.Println("b:", b, " &b[0]:", &b[0], " len:", len(b), " cap:", cap(b))
- }
如果append的元素数较多,超过了原来的容量,直接采用了新的底层数组,也就不会影响到a了。
输出:
- a: [10 20] &a[0]: 0xc0000105a0 len: 2 cap: 4
- a: [10 20] &a[0]: 0xc0000105a0 len: 2 cap: 4
- b: [10 1 2 3 4] &b[0]: 0xc000014240 len: 5 cap: 8
- package main
- import (
- "fmt"
- )
- func testAppend(s []int) {
- //进行append操作
- s = append(s, 1)
- //s: [10 1] &s[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("s:", s, " &s[0]:", &s[0], " len:", len(s), " cap:", cap(s))
- }
- func main() {
- a := make([]int, 2, 4)
- a[0] = 10
- a[1] = 20
- //a: [10 20] &a[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- testAppend(a[:1])
- //a: [10 1] &a[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- }
输出:
- a: [10 20] &a[0]: 0xc0000105a0 len: 2 cap: 4
- s: [10 1] &s[0]: 0xc0000105a0 len: 2 cap: 4
- a: [10 1] &a[0]: 0xc0000105a0 len: 2 cap: 4
- import (
- "fmt"
- )
- func testAppend(s []int) {
- //进行append操作
- s = append(s, 1, 2, 3, 4)
- //s: [10 1] &s[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("s:", s, " &s[0]:", &s[0], " len:", len(s), " cap:", cap(s))
- }
- func main() {
- a := make([]int, 2, 4)
- a[0] = 10
- a[1] = 20
- //a: [10 20] &a[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- testAppend(a[:1])
- //a: [10 1] &a[0]: 0x10410020 len: 2 cap: 4
- fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
- }
输出
- a: [10 20] &a[0]: 0xc0000105a0 len: 2 cap: 4
- s: [10 1 2 3 4] &s[0]: 0xc000014240 len: 5 cap: 8
- a: [10 20] &a[0]: 0xc0000105a0 len: 2 cap: 4
参考:
golang学习笔记 ---slice的更多相关文章
- golang学习笔记20 一道考察对并发多协程操作一个共享变量的面试题
golang学习笔记20 一道考察对并发多协程操作一个共享变量的面试题 下面这个程序运行的能num结果是什么? package main import ( "fmt" " ...
- golang学习笔记19 用Golang实现以太坊代币转账
golang学习笔记19 用Golang实现以太坊代币转账 在以太坊区块链中,我们称代币为Token,是以太坊区块链中每个人都可以任意发行的数字资产.并且它必须是遵循erc20标准的,至于erc20标 ...
- golang学习笔记18 用go语言编写移动端sdk和app开发gomobile
golang学习笔记18 用go语言编写移动端sdk和app开发gomobile gomobile的使用-用go语言编写移动端sdk和app开发https://blog.csdn.net/u01249 ...
- golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍
golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍 go语言爬虫框架:gocolly/colly,goquery,colly,chrom ...
- golang学习笔记16 beego orm 数据库操作
golang学习笔记16 beego orm 数据库操作 beego ORM 是一个强大的 Go 语言 ORM 框架.她的灵感主要来自 Django ORM 和 SQLAlchemy. 目前该框架仍处 ...
- golang学习笔记14 golang substring 截取字符串
golang学习笔记14 golang substring 截取字符串golang 没有java那样的substring函数,但支持直接根据 index 截取字符串mystr := "hel ...
- golang学习笔记13 Golang 类型转换整理 go语言string、int、int64、float64、complex 互相转换
golang学习笔记13 Golang 类型转换整理 go语言string.int.int64.float64.complex 互相转换 #string到intint,err:=strconv.Ato ...
- golang学习笔记12 beego table name `xxx` repeat register, must be unique 错误问题
golang学习笔记12 beego table name `xxx` repeat register, must be unique 错误问题 今天测试了重新建一个项目生成新的表,然后复制到旧的项目 ...
- golang学习笔记11 golang要用jetbrain的golang这个IDE工具开发才好
golang学习笔记11 golang要用jetbrain的golang这个IDE工具开发才好 jetbrain家的全套ide都很好用,一定要dark背景风格才装B 从File-->s ...
随机推荐
- 英语chrismatite黄蜡石chrismatite单词
黄蜡石chrismatite的原岩均为硅质岩,各种原岩受到构造变动.火山活动.热液作用等影响,产生复杂的物理和化学变化,包括重结晶.热变质等,导致矿物成分及结构构造的变化,后受构造变动的影响,岩石露出 ...
- OPC 集成的五大要素,你都掌握了吗?
相信在处理工业项目集成问题的时候,自动化集成供应商真正需要的不是那些华丽的宣传语,而是提供真正的通信数据集成实力. 任何自动化集成的供应商都希望能够消除中间的层层障碍,从而实现真正的信息集成互通.那么 ...
- 章节十四、2-自动完成功能-Autocomplete
一.什么是自动匹配功能? 很多网站都有自动匹配功能,列如你在使用天猫搜索商品时,输入“鞋”,输入框的下面会出现很多与“鞋”有关的选项. 二.以https://www.expedia.com/网站的城市 ...
- php中mysqli_error($conn)的用法
注意:用函数判断sql语句是否有错需要把这个函数写在mysqli_query("$conn连接语句","$sql语句")后面才能进行检测. 返回值:返回最近调用 ...
- 起步:SpringBoot
pom.xml <parent> <groupId>org.springframework.boot</groupId> <artifactId>spr ...
- Python 简易的异步协程使用方法
代码 import asyncio async def ex(id, n): print(id+" start") await asyncio.sleep(n/2) print(i ...
- Java八大排序之希尔(Shell)排序
希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该 ...
- 重写jquery ajax 方法
方法一 // TODO 主要功能为重写ajax $.ajaxSetup({ cache: false, headers: { "xxxxx": "xxxxx" ...
- djangoORM 修改表结构/字段/外键操作
Django支持修改表结构 把max_length=64 改为60 再执行一遍 python manage.py makemigrations python manage.py migrate 如果是 ...
- leetcode206. 反转链表
1:迭代法 假设存在链表 1 → 2 → 3 → Ø,我们想要把它改成 Ø ← 1 ← 2 ← 3. 在遍历列表时,将当前节点的 next 指针改为指向前一个元素.由于节点没有引用其上一个节点,因此必 ...