当前位置:网站首页>GO语言-Slice切片
GO语言-Slice切片
2022-06-11 15:36:00 【一边学习一边哭】
前言
切片Slice,与数组相似。也叫变长数组或者动态数组。特点:变长。
Slice是一个引用类型的容器,指向了一个底层数组。
创建slice语法
常规操作
var slice_name []type
slice_name := []type{v1, v2, v3, v4}在已有数组上创建切片
//切片名 := 数组[开始下标, 结束下标] 注意:不包含结束下标
slice_name := array_name[start:end]func main() {
arr := [9]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
slice_test1 := arr[1:4] //2-4
slice_test2 := arr[:5] //1-5
slice_test3 := arr[5:] //6-9
slice_test4 := arr[:] //1-9
fmt.Println(slice_test1)
fmt.Println(slice_test2)
fmt.Println(slice_test3)
fmt.Println(slice_test4)
}make关键字创建slice
make关键字专门用于创建引用类型的数据。
语法
make(type, size1, size2)第一个参数是类型 slice、map、chan
第二个参数是长度
第三个参数是容量。
存储长度超过容量时,会自动扩容。
默认存储数据,int类型时使用0填充;string类型时使用空字符串填充。可以通过下标操作默认已存在的值。
func main() {
slice_test1 := make([]int, 3, 5)
fmt.Printf("slice_test1: %v; slice长度: %v; slice容量: %v\n", slice_test1, len(slice_test1), cap(slice_test1))
//append元素,超过slice容量
slice_test1 = append(slice_test1, 1, 2, 3)
fmt.Println("---append后---")
fmt.Printf("slice_test1: %v; slice长度: %v; slice容量: %v\n", slice_test1, len(slice_test1), cap(slice_test1))
}
slice赋值操作对底层数组的影响
- 对array元素操作时,所有指向array的slice的元素也会发生改变。
- 对slice中元素操作时,实际时对array的元素进行操作。
- slice发生扩容时,实际是开辟了新的内存空间,所以原来的array不会发生改变。
具体示例
1.当底层数组改变时,所有指向这个array的slice响应索引位置上的值也会发生改变。
func main() {
arr := [6]int{1, 2, 3, 4, 5, 6}
slice_test1 := arr[:]
slice_test2 := arr[:3]
slice_test3 := arr[3:]
fmt.Println("slice_test1:", slice_test1)
fmt.Println("slice_test2:", slice_test2)
fmt.Println("slice_test3:", slice_test3)
arr[1] += 1
arr[4] += 1
fmt.Println("---对array元素操作后---")
fmt.Println("slice_test1:", slice_test1)
fmt.Println("slice_test2:", slice_test2)
fmt.Println("slice_test3:", slice_test3)
} 
2.当操作slice内容时,比如从slice[index]修改索引位置上的值或者使用append新增值时,都是对底层数组进行操作。所以同(1),其他指向这个array的slice对应的位置也会发生改变。
func main() {
arr := [6]int{1, 2, 3, 4, 5, 6}
slice_test1 := arr[:]
slice_test2 := arr[:3]
slice_test3 := arr[3:]
fmt.Println("slice_test1:", slice_test1)
fmt.Println("slice_test2:", slice_test2)
fmt.Println("slice_test3:", slice_test3)
slice_test1[1] += 1
slice_test1[4] += 1
fmt.Println("---对slice元素操作后---")
fmt.Println("slice_test1:", slice_test1)
fmt.Println("slice_test2:", slice_test2)
fmt.Println("slice_test3:", slice_test3)
}
3.当使用append给slice增加值,操作slice容量,slice发生扩容。slice扩容时,会开辟新的内存地址。将原有的array内的值复制过来;进行扩容后再加入新的值。所以扩容情况下所新增的值不会对原有的array进行操作。
所以slice发生扩容时,只有被扩容的slice内的值发生变化。array不会发生变化,其他指向原有array的slice中的值也不会发生变化。
func main() {
arr := [6]int{1, 2, 3, 4, 5, 6}
slice_test1 := arr[:]
slice_test2 := arr[:3]
slice_test3 := arr[3:]
fmt.Printf("slice_test1: %v; slice_test1长度: %v; slice_test1容量: %v \n", slice_test1, len(slice_test1), cap(slice_test1))
fmt.Println("slice_test2:", slice_test2)
fmt.Println("slice_test3:", slice_test3)
slice_test1 = append(slice_test1, 7, 8, 9)
slice_test1[1] += 1
slice_test1[4] += 1
fmt.Println("---slice_test1发生扩容时---")
fmt.Println("原数组arr:", arr)
fmt.Println("slice_test1:", slice_test1)
fmt.Println("slice_test2:", slice_test2)
fmt.Println("slice_test3:", slice_test3)
}
append插入元素
语法
slice_name = append(slice_name, v1, v2)
slice_name = append(slice_name, slicename2...)可以把slice_name2切片的值全部插入slice_name中。但是slice_name2后面必须有三个点,表示时切片。
func main() {
slice_test1 := []int{1, 2, 3}
slice_test2 := []int{4, 5, 6}
fmt.Println("append前slice_test1:", slice_test1)
slice_test1 = append(slice_test1, slice_test2...)
fmt.Println("appendslice_test2后slice_test1:", slice_test1)
slice_test1 = append(slice_test1, 7, 8, 9)
fmt.Println("append单个元素后slice_test1:", slice_test1)
}
切片Slice内存分析
查看内存地址的时候。数值类型,如array、int等,fmt.Printf(%p\n, &arr) ,要再变量前加上&符号;引用类型,如slice,fmt.Printf(%p\n, slice1) ,不需要加&符号。
func main() {
s1 := []int{1, 2, 3, 4}
fmt.Println(s1)
fmt.Printf("s1的地址: %p; s1的长度: %v; s1的容量: %v \n", s1, len(s1), cap(s1))
s1 = append(s1, 5, 6)
fmt.Println(s1)
fmt.Printf("s1的地址: %p; s1的长度: %v; s1的容量: %v \n", s1, len(s1), cap(s1))
}
1.创建数组s1时,是先创建一个底层数组。然后再用切片s1指向底层数组。此时长度和容量一样。
2.切片本身不存储数据,都是底层数组存储数据。所以修改也是修改底层数组。
3.扩容:底层数组扩容时,其容量都是成倍扩容的。所以使用append操作切片,发生扩容时,slice的容量也是成倍扩容。
4.因为扩容要改变底层数组,所以底层数组的内存地址发生了改变;如果不需要扩容,内存地址就不会发生改变。
边栏推荐
- CF662B Graph Coloring题解--zhengjun
- Uniapp développe des applets Wechat, de la construction à la mise en ligne
- Number system conversion (function)
- Introduction to thread practice [hard core careful entry!]
- 05 _ 深入浅出索引(下)
- See from the minute, carve on the details: Exploration of SVG generated vector format website icon (favicon)
- Uniapp develops wechat applet from build to launch
- [mysql_11] addition, deletion and modification of data processing
- Art plus online school: Sketch common sitting posture test questions, these three angles must be mastered~
- openGauss数据库性能调优概述及实例分析
猜你喜欢

三千字教你使用MOT
![[creation mode] abstract factory mode](/img/16/d0086ba4cceb1c174d3f88ef5448e6.png)
[creation mode] abstract factory mode

openGauss数据库ODBC环境连接配置(Windows)

openGauss 多线程架构启动过程详解

2022年软件测试的前景如何?需不需要懂代码?

Uniapp développe des applets Wechat, de la construction à la mise en ligne
![Introduction to thread practice [hard core careful entry!]](/img/1c/1f6422ba8fbeeb1c094ba7b1da2b78.png)
Introduction to thread practice [hard core careful entry!]

数据库资源负载管理(下篇)

openGauss AI能力升级,打造全新的AI-Native数据库

openGauss并行解码浅谈
随机推荐
CF662B Graph Coloring题解--zhengjun
[creation mode] builder mode
Hebei huangjinzhai scenic spot adds "AED automatic defibrillator" to ensure the life safety of tourists!
使用Cloud DB构建APP 快速入门-快应用篇
JVM基础概念入门
中山大学大气院徐伟新教授团队关于弱对流造成极端降水的研究成果被Science亮点报道
Implementation of placing the scroll bar on the top of the uniapp
数据库资源负载管理(下篇)
我的代码变量名称统一 记录
Number system conversion (function)
openGauss数据库JDBC环境连接配置(Eclipse)
[0006] title, keyword and page description
openGauss企业版安装
向数据库导入数据?试试COPY FROM STDIN语句
Methodology and practice of real-time feature computing platform architecture
Arthas实践操作文档记录
Hard core analysis lazy single case
英伟达终于开源GPU内核模块代码,网友:难以置信
【MongoDB】4. Usage specification of mongodb
The reason why it is easy to let the single chip computer program fly