golang 切片(slice)
1.切片的定义
切片(slice)是对数组一个连续片段的引用,所以切片是一个引用类型。
切片的使用与数组类似,遍历,访问切片元素等都一样。切片是长度是可以变化的,因此切片可以看做是一个动态数组。
- 一个切片由三个部分构成:底层数组的指针、长度(len)和容量(cap),指针指向该切片自己第一个元素对应的底层数组元素的内存地址,容量可以容纳最多元素的个数,默认为2*len。
- cap可以求出slice最大扩张容量,不能超出数组限制。0 <= len(slice) <= len(array),其中array是slice引用的数组。
2.切片初始化
2.1 定义一个切片,然后让切片去引用一个已经创建好的数组。
package main
import "fmt"
func main() {
var arr1 = [8]int{0, 1, 2, 3, 4, 5, 6, 7} //定义数组arr1,长度为8
var slice []int = arr1[0:4] //可以简写为slice := arr1[0:4]
slice1 := arr1[0:4] //从0下标开始,到4下标结束,不包含下标为4的值。
slice2 := arr1[:5] //从开头开始(0下标),到下标为5结束,不包含下标为5的值。
slice3 := arr1[6:] //从6下标开始,到数组末尾结束。
slice4 := arr1[:] //获取全部数组。
fmt.Printf("slice的值为:%v,slice的长度为:%v,slice容量为:%v\n", slice, len(slice), cap(slice))
fmt.Printf("slice1的值为:%v,slice1的长度为:%v,slice1容量为:%v\n", slice1, len(slice1), cap(slice1))
fmt.Printf("slice2的值为:%v,slice2的长度为:%v,slice2容量为:%v\n", slice2, len(slice2), cap(slice2))
fmt.Printf("slice3的值为:%v,slice3的长度为:%v,slice3容量为:%v\n", slice3, len(slice3), cap(slice3))
fmt.Printf("slice4的值为:%v,slice4的长度为:%v,slice4容量为:%v\n", slice4, len(slice4), cap(slice4))
}
执行结果
slice的值为:[0 1 2 3],slice的长度为:4,slice容量为:8
slice1的值为:[0 1 2 3],slice1的长度为:4,slice1容量为:8
slice2的值为:[0 1 2 3 4],slice2的长度为:5,slice2容量为:8
slice3的值为:[6 7],slice3的长度为:2,slice3容量为:2
slice4的值为:[0 1 2 3 4 5 6 7],slice4的长度为:8,slice4容量为:8
2.2 定一个切片,直接就指定具体数组
package main
import "fmt"
func main() {
a := []int{} //空切片,和nil不相等,一般用来表示一个空的集。
b := []int{0, 1, 2} //有3个元素的切片。
fmt.Printf("a的值为:%v,a的长度为:%v,a容量为:%v\n", a, len(a), cap(a))
fmt.Printf("b的值为:%v,b的长度为:%v,b容量为:%v\n", b, len(b), cap(b))
}
执行结果
a的值为:[],a的长度为:0,a容量为:0
b的值为:[0 1 2],b的长度为:3,b容量为:3
2.3. make创建切片
基本语法: var切片名[]type = make([]type, len, cap) //[]type为切片类型,len为切片长度,cap为切片容量
package main
import "fmt"
func main() {
slice1 := make([]int, 5, 10) //定义长度为5,容量为10的切片,没有赋值,所以切片的值都为int类型的默认值0
fmt.Printf("slice的值为:%v,slice的长度为:%v,slice容量为:%v\n", slice1, len(slice1), cap(slice1))
slice1[3] = 10 //给slice切片下标为3,赋值为10.
fmt.Printf("slice的值为:%v\n", slice1)
slice2 := make([]string, 4) //不指定容量,默认容量跟长度一致
fmt.Printf("slice2的值为:%v,slice2的长度为:%v,slice2容量为:%v\n", slice2, len(slice2), cap(slice2))
}
执行结果
slice的值为:[0 0 0 0 0],slice的长度为:5,slice容量为:10
slice的值为:[0 0 0 10 0]
slice2的值为:[ ],slice2的长度为:4,slice2容量为:4
3. 切片的遍历
3.1 for循环遍历
package main
import "fmt"
func main() {
var slice1 = []int{1, 2, 3, 4, 5}
for i := 0; i < len(slice1); i++ {
fmt.Printf("下标为%v的值为:%v\n", i, slice1[i])
}
}
执行结果
下标为0的值为:1
下标为1的值为:2
下标为2的值为:3
下标为3的值为:4
下标为4的值为:5
3.2 for range遍历
package main
import "fmt"
func main() {
var slice1 = []int{1, 2, 3, 4, 5}
for k1, v1 := range slice1 {
fmt.Printf("下标为%v的值为:%v\n", k1, v1)
}
}
执行结果
下标为0的值为:1
下标为1的值为:2
下标为2的值为:3
下标为3的值为:4
下标为4的值为:5
4.切片的内存
切片下标为0的内存地址,对应底层数组的开始位置的内存地址,当修改切片的值时,因为切片的内存地址和数组中截取的数据内存地址相同,数组的值也会修改。
package main
import "fmt"
func main() {
var arr1 = [8]int{1, 2, 3, 4, 5, 6, 7, 8}
var slice1 = arr1[1:4] //取arr1数组下标为1,2,3的,[2,3,4]
fmt.Printf("arr1的值为:%v,arr1的内存地址为:%p\n", arr1, &arr1[1])
fmt.Printf("slice1的值为:%v,slice1的内存地址为:%p\n", slice1, &slice1[0])
slice1[0] = 10
fmt.Printf("修改后arr1的值为:%v\n", arr1)
fmt.Printf("修改后slice1的值为:%v\n", slice1)
}
执行结果
arr1的值为:[1 2 3 4 5 6 7 8],arr1的内存地址为:0xc00001a308
slice1的值为:[2 3 4],slice1的内存地址为:0xc00001a308
修改后arr1的值为:[1 10 3 4 5 6 7 8]
修改后slice1的值为:[10 3 4]
5. append方法
package main
import "fmt"
func main() {
slice1 := []int{1, 2, 3, 4, 5, 6, 7, 8}
fmt.Printf("slice1切片的值为:%v,slice1的长度为%v,slice1的容量为:%v\n", slice1, len(slice1), cap(slice1))
slice1 = append(slice1, 9) //在切片slice1后面添加一个元素9
fmt.Printf("slice1切片的值为:%v,slice1的长度为%v,slice1的容量为:%v\n", slice1, len(slice1), cap(slice1))
slice1 = append(slice1, 10, 11, 12) //在切片slice1后面添加三个元素,10,11,12
fmt.Printf("slice1切片的值为:%v,slice1的长度为%v,slice1的容量为:%v\n", slice1, len(slice1), cap(slice1))
slice2 := [][]int{[]int{1, 2, 3}} //定义slice2,里面的数据类型为切片
fmt.Printf("slice2切片的值为:%v,slice2的长度为%v,slice2的容量为:%v\n", slice2, len(slice2), cap(slice2))
slice2 = append(slice2, slice1) //将slice1切片追加到slice2里面
fmt.Printf("slice2切片的值为:%v,slice2的长度为%v,slice2的容量为:%v\n", slice2, len(slice2), cap(slice2))
}
执行结果
slice1切片的值为:[1 2 3 4 5 6 7 8],slice1的长度为8,slice1的容量为:8
slice1切片的值为:[1 2 3 4 5 6 7 8 9],slice1的长度为9,slice1的容量为:16
slice1切片的值为:[1 2 3 4 5 6 7 8 9 10 11 12],slice1的长度为12,slice1的容量为:16
slice2切片的值为:[[1 2 3]],slice2的长度为1,slice2的容量为:1
slice2切片的值为:[[1 2 3] [1 2 3 4 5 6 7 8 9 10 11 12]],slice2的长度为2,slice2的容量为:2
6. copy方法
package main
import "fmt"
func main() {
slice1 := []int{1, 2, 3, 4, 5, 6, 7, 8}
fmt.Printf("slice1切片的值为:%v\n", slice1)
slice2 := []int{9, 10}
fmt.Printf("slice2切片的值为:%v\n", slice2)
//内置函数copy将切片slice2中的值拷贝到slice1中将slice1中的前len(slice2)个的元素值覆盖掉。
//slice1和slice1的数据空间是相互隔离的,互不影响。若将slice1[1]设置为2,则slice2[1]仍为10而不随着若将slice1[1]的改变而改变。
copy(slice1, slice2) //将slice2元素copy到slice1
fmt.Printf("slice1切片的值为:%v\n", slice1)
//注意:由于切片是引用类型,所以slice3和slice4其实都指向了同一块内存地址。
//修改slice4的同时slice3的值也会发生变化。
slice3 := []int{1, 2, 3}
slice4 := slice3
fmt.Printf("slice3切片的值为:%v,slice3[0]的内存地址为:%p,slice3[1]的内存地址为:%p,slice3[2]的内存地址为:%p,\n", slice3, &slice3[0], &slice3[1], &slice3[2])
fmt.Printf("slice4切片的值为:%v,slice4[0]的内存地址为:%p,slice4[1]的内存地址为:%p,slice4[2]的内存地址为:%p,\n", slice4, &slice4[0], &slice4[1], &slice4[2])
slice4[0] = 10
fmt.Printf("slice3的值为:%v\n", slice3)
fmt.Printf("slice4的值为:%v\n", slice4)
}
执行结果
slice1切片的值为:[1 2 3 4 5 6 7 8]
slice2切片的值为:[9 10]
slice1切片的值为:[9 10 3 4 5 6 7 8]
slice3切片的值为:[1 2 3],slice3[0]的内存地址为:0xc000010120,slice3[1]的内存地址为:0xc000010128,slice3[2]的内存地址为:0xc000010130,
slice4切片的值为:[1 2 3],slice4[0]的内存地址为:0xc000010120,slice4[1]的内存地址为:0xc000010128,slice4[2]的内存地址为:0xc000010130,
slice3的值为:[10 2 3]
slice4的值为:[10 2 3]
golang 切片(slice)的更多相关文章
- golang切片slice
切片slice是引用类型 len()函数获取元素的个数 cap()获取数组的容量 1.申明方式 (1)var a []int 与数组不同的是他不申明长度(2)s2 := make([]int, 3, ...
- Golang 入门 : 切片(slice)
切片(slice)是 Golang 中一种比较特殊的数据结构,这种数据结构更便于使用和管理数据集合.切片是围绕动态数组的概念构建的,可以按需自动增长和缩小.切片的动态增长是通过内置函数 append( ...
- 转 Golang 入门 : 切片(slice)
https://www.jianshu.com/p/354fce23b4f0 切片(slice)是 Golang 中一种比较特殊的数据结构,这种数据结构更便于使用和管理数据集合.切片是围绕动态数组的概 ...
- golang基础---Slice切片
切片Slice在go语言中是单独的类型(指向底层的数组),不同于python(对可迭代对象操作的工具),注意区分数组和slice的区别 定义一个空slice,格式var s []int,这种既没有长度 ...
- Go 灵活多变的切片Slice
我们知道数组定义好之后其长度就无法再修改,但是,在实际开发过程中,有时候我们并不知道需要多大的数组,我们期望数组的长度是可变的, 在 Go 中有一种数据结构切片(Slice) 解决了这个问题,它是可变 ...
- [Golang]-1 Slice与数组的区别
目录 数组 1.创建数组: 2.数组是值拷贝传递: 切片(slice) 1.首先看看slice的源码结构: 2.slice的创建: 3.slice使用make创建 4.切片作为参数传递 5.Golan ...
- go 数组(array)、切片(slice)、map、结构体(struct)
一 数组(array) go语言中的数组是固定长度的.使用前必须指定数组长度. go语言中数组是值类型.如果将数组赋值给另一个数组或者方法中参数使用都是复制一份,方法中使用可以使用指针传递地址. 声明 ...
- 在python&numpy中切片(slice)
在python&numpy中切片(slice) 上文说到了,词频的统计在数据挖掘中使用的频率很高,而切片的操作同样是如此.在从文本文件或数据库中读取数据后,需要对数据进行预处理的操作.此时就 ...
- golang切片数据结构解释
1. 切片:切片是数组的一个引用,因此切片是引用类型 func main() { var arr = [6]int{1, 2, 3, 4, 5} var slice = arr[1:] fmt.Pri ...
- golang切片类型
切片slice 其本身并不是数组,它指向底层的数组 作为变长数组的替代方案,可以关联底层数组的局部或全部 为引用类型 可以直接创建或从底层数组获取生成 使用len()获取元素个数,cap()获取容量 ...
随机推荐
- hashlib 模块 subprocess 模块 logging日志模块
今日内容 hashlib加密模块 1.何为加密 将明文数据处理成密文数据 让人看不懂 2.为什么加密 保证数据的安全 3.如何判断数据是否加密的 一串没有规律的字符串(数字.字母.符号) 4.密文的长 ...
- Hugging Face 开源库介绍
Hugging Face 的开源生态今年成长迅速,timm 成为新加入的成员.diffusers.evaluate 以及 skops 等各种库蓬勃发展. Transformers Transforme ...
- ChatGPT开发实战
1.概述 前段时间使用体验了ChatGPT的用法,感受到ChatGPT的强大,通过搜索关键字或者输入自己的意图,能够快速得到自己想要的信息和结果.今天笔者将深挖一下ChatGPT,给大家介绍如何使用C ...
- 特定领域知识图谱融合方案:文本匹配算法(Simnet、Simcse、Diffcse)
特定领域知识图谱融合方案:文本匹配算法(Simnet.Simcse.Diffcse) 本项目链接:https://aistudio.baidu.com/aistudio/projectdetail/5 ...
- 如何通过Java代码向Word文档添加文档属性
Word文档属性包括常规.摘要.统计.内容.自定义.其中摘要包括标题.主题.作者.经理.单位.类别.关键词.备注等项目.属性相当于文档的名片,可以添加你想要的注释.说明等.还可以标注版权. 今天就为大 ...
- touchke变化值小的解决办法
方法一,提高主频 方法二,减小充电时间. 方法三,充电电流减半(具体看RM手册touchkey章节) 建议测试时采样值维持在3000-4000 其实以上操作就是增大Y轴间隔,以增大按下和未按下时的采样 ...
- 12月2日内容总结——边框属性,display属性,css盒子模型,浮动、溢出、定位、z-index属性和建议博客页面搭建
目录 一.边框 边框简介 border-style--边框样式 border-width--边框宽度 border-color--边框颜色 二.display属性 三.CSS盒子模型 概念 margi ...
- 构建api gateway之 如何给openresty打patch
如何给openresty打patch 由于很多功能实现的限制,我们不得不修改openresty,但我们又不一定能持续维护一个 openresty 分支,所有有了patch 这一操作. patch是怎么 ...
- CSS常用属性(2)
(4) position(定位) fixed 一般用来写网页顶端的固定导航条,或者两侧的菜单. <!--对于块级标签来说加上position:fixed之后,该div就不会占一整行,一般需要手动 ...
- SpringBoot2.6.x及以上版本整合swagger文档
SpringBoot的版本更新中引入了一些新的特性,并且Swagger的版本更新也同样引入了很多新的东西,这样就造成了许多配置无法实现一一对应的情况,因此高版本的SpringBoot集成Swagger ...