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)的更多相关文章

  1. golang切片slice

    切片slice是引用类型 len()函数获取元素的个数 cap()获取数组的容量 1.申明方式 (1)var a []int 与数组不同的是他不申明长度(2)s2 := make([]int, 3, ...

  2. Golang 入门 : 切片(slice)

    切片(slice)是 Golang 中一种比较特殊的数据结构,这种数据结构更便于使用和管理数据集合.切片是围绕动态数组的概念构建的,可以按需自动增长和缩小.切片的动态增长是通过内置函数 append( ...

  3. 转 Golang 入门 : 切片(slice)

    https://www.jianshu.com/p/354fce23b4f0 切片(slice)是 Golang 中一种比较特殊的数据结构,这种数据结构更便于使用和管理数据集合.切片是围绕动态数组的概 ...

  4. golang基础---Slice切片

    切片Slice在go语言中是单独的类型(指向底层的数组),不同于python(对可迭代对象操作的工具),注意区分数组和slice的区别 定义一个空slice,格式var s []int,这种既没有长度 ...

  5. Go 灵活多变的切片Slice

    我们知道数组定义好之后其长度就无法再修改,但是,在实际开发过程中,有时候我们并不知道需要多大的数组,我们期望数组的长度是可变的, 在 Go 中有一种数据结构切片(Slice) 解决了这个问题,它是可变 ...

  6. [Golang]-1 Slice与数组的区别

    目录 数组 1.创建数组: 2.数组是值拷贝传递: 切片(slice) 1.首先看看slice的源码结构: 2.slice的创建: 3.slice使用make创建 4.切片作为参数传递 5.Golan ...

  7. go 数组(array)、切片(slice)、map、结构体(struct)

    一 数组(array) go语言中的数组是固定长度的.使用前必须指定数组长度. go语言中数组是值类型.如果将数组赋值给另一个数组或者方法中参数使用都是复制一份,方法中使用可以使用指针传递地址. 声明 ...

  8. 在python&numpy中切片(slice)

     在python&numpy中切片(slice) 上文说到了,词频的统计在数据挖掘中使用的频率很高,而切片的操作同样是如此.在从文本文件或数据库中读取数据后,需要对数据进行预处理的操作.此时就 ...

  9. golang切片数据结构解释

    1. 切片:切片是数组的一个引用,因此切片是引用类型 func main() { var arr = [6]int{1, 2, 3, 4, 5} var slice = arr[1:] fmt.Pri ...

  10. golang切片类型

    切片slice 其本身并不是数组,它指向底层的数组 作为变长数组的替代方案,可以关联底层数组的局部或全部 为引用类型 可以直接创建或从底层数组获取生成 使用len()获取元素个数,cap()获取容量 ...

随机推荐

  1. 如何在Github上创建一个新仓库

    Hi,欢迎大家在有空的时候做客[江涛学编程],这里是2023年的第6篇原创文章,新年新气象,在这里我祝读者朋友们都好好的, 老规矩,拍拍手,上菜. 今天没有啥东西要跟家人们分享,就两个字,看图!!! ...

  2. Web初级——JavaScript

    JavaScript JavaScript是一种基于对象的脚本语言,用于开发基于客户端和基于服务器的Internet应用程序 1.了解JS 1.1JavaScript的组成 JavaScript 的核 ...

  3. 数据结构与算法 -> 并查集

    一.并查集概念 并查集是一种树形的数据结构,顾名思义,它用于处理一些不交集的合并及查询问题. 它支持两种操作: 查找(Find):确定某个元素处于哪个子集,单次操作时间复杂度 O(α(n)),即查询元 ...

  4. 企业应用架构研究系列十三:整合EFCore&Dapper 通用ORM框架EFDapper

    EntityFrameworkCore是微软官网提供的ORM框架,是轻量化.可扩展.开源和跨平台的数据访问技术框架,但是在.Net 开发圈的评论却褒贬不一.很多人认为EFCore 执行的效能比较差,很 ...

  5. redisConfig+redisUtil开箱即用

    RedisConfig @Configuration public class RedisConfig { //编写redisTemplate //固定模板,开箱即用 @Bean public Red ...

  6. ApiView/Request类源码分析/序列化器

    内容概要 ApiView+JsonResponse编写接口 ApiView+Response编写接口 ApiView源码解析 Request对象源码分析 序列化器介绍和快速使用/反序列化 反序列化的校 ...

  7. Java 进阶P-8.1+P-8.2

    捕捉异常 异常的处理方式之一:捕获异常 捕获异常是通过3个关键词来实现的:try-catch-finally.用try来执行一段程序,如果出现异常,系统抛出一个异常,可以通过它的类型来捕捉(catch ...

  8. Windows离线安装.net Framework3.5

    写在前面 本文主要介绍在Windows离线情况下安装.NETFramework3.5运行环境 使用场景 在日常开发C#程序中,经常会遇到开发过程中无任何问题,但是安装到目标电脑是会无法打开的,如下图 ...

  9. java画海报

    package demotest; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; impor ...

  10. 爬虫Charles安装破解使用教程

    转:https://blog.csdn.net/qq_27109535/article/details/125787745 1 下载安装程序及破解包 链接:https://pan.baidu.com/ ...