include

  1. 切片
  2. 切片的日常用法

切片slice

  • 其本身并不是数组,它指向底层的数组
  • 作为变长数组的替代方案,可以关联底层数组的局部或者
  • 为引用类型。
  • 可以直接创建或从底层数组获取生成。
  • 使用len()获取元素个数,cap()获取容量
  • 一般使用make()创建
  • 如果多个slice指向相同底层数组,其中一个的值改变会影响全部。
  • make([]T,len,cap)
  • 其中cap可以省略,则和Len的值相同。
  • len()表示存数的元素个数,cap表示容量
最简单的切片:

先看看如何切片,我们先定义一个数组,然后开始切片,切片我们是根据输入的下标来取值的。

切片的包含关系是,包左不包右,什么意思呢?就是在做切片处理的时候,右边结束的下标是不取,只取左边开始的下标到右边结束下标的前一位值。

func main() {
a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
fmt.Println(a)
s1 := a[5:7]
fmt.Println(s1)
}

切片常用方法:

  1. 从某一位下标取到最后一位下标
  2. 从第一位下标到指定的某一位下标
func main() {
a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
fmt.Println(a)
s1 := a[5:7]
s2 := a[6:len(a)] // 从某一位下标取到最后一位下标
s3 := a[5:] // 从某一位下标取到最后一位下标
s4 := a[:5] // 从第一位下标到指定的某一位下标
fmt.Println(s1, s2, s3, s4)
}

通过切片获取这个数组的所有值

我们可以通过切片获取这个数组的所有值

func main() {
s1 := []int{1, 2, 3, 4, 5, 6}
s2 := s1[:]
fmt.Println(s1, s2)
}

打印的结果如下:

func main() {
s1 := []int{1, 2, 3, 4, 5, 6}
s2 := s1[:]
fmt.Println(s1, s2)
}

make 制作切片

make 语法要点:

make(数组类型,包含多少个元素,容量)

举个例子,比如你这个数组的长度没有超过容量,那么就不需额外重新分配内存,

如超过了这个长度,那么就需要重新分配一倍的内存地址给她,比如初试容量为10,

那么下次分配容量就是20了。

如果容量没有设置的话,那么就默认使用元素的个数作为当前的容量。

func main() {
s1 := make([]int, 3, 10) // int类型数组,包含多少个元素,容量。
/* 举个例子,比如你这个数组的长度没有超过容量,那么就不需额外重新分配内存,
如超过了这个长度,那么就需要重新分配一倍的内存地址给她,比如初试容量为10,
那么下次分配容量就是20了。
如果容量没有设置的话,那么就默认使用元素的个数作为当前的容量 */
fmt.Println(s1, cap(s1), len(s1))
}
	s2 := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'g'}
sa := s2[2:5]
sb := sa[3:5] // 此时取sa[3:5]分片等于以s2的下标为2的元素开始
fmt.Println(string(sb), string(sa))

Reslice

  • Reslice时索引以被slice的切片为准
  • 索引不可以超过slice的切片的容量cap()值
  • 索引越界不会导致底层数组重新分配而是引发错误,也就是切片不了了。
slice与底层数组的对应关系

每次切片得出来的新数组,其实这个数组的容量就是从这个切片的开始位置到被切片数组最后一位,什么意思呢?看下面的代码讲解

func main() {
s2 := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'g'}
sa := s2[2:5]
fmt.Println(cap(sa), len(sa)) // 此时sa的容量是8,8就是从下标为2开始的元素到末尾,总共8个元素
sb := sa[3:5] // 此时取sa[3:5]分片等于以s2的下标为2的元素开始
fmt.Println(string(sb), string(sa))
}

修改切片出来的数组同时会影响其他切片数组

	a := []int{1, 2, 3, 4, 5}
s1 := a[2:5]
s2 := a[1:3]
fmt.Println(s1, s2)
s1[0] = 9
fmt.Println(s1, s2)

打印的结果如下:

[3 4 5] [2 3]
[9 4 5] [2 9]

显然结果很明显,我们在修改s1的数组的时候,也修改了原始数组,同时,也影响到了对这个原始数组切片的其他数组。但是对于append,就不会这样了。因为append会返回一个新的数组,是不受影响的。

Append

  • 可以在slice尾部追加元素
  • 可以将一个slice追加在另一个slice尾部
  • 如果最终长度没有超过追加到slice的容量则返回原始slice
  • 如果超过追加到的slice的容量,则重新分配数组并拷贝原始数据。

代码例子:

func main() {
a := []int{1, 2, 3, 4, 5}
s1 := a[2:5]
s2 := a[1:3]
fmt.Println(a, s1, s2)
s2 = append(s2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
s1[0] = 9
fmt.Println(a, s1, s2)
}

我们看下打印结果:

[1 2 9 4 5] [9 4 5] [2 3 1 2 3 4 5 6 7 8 9 10]

由打印结果可得:s2不受影响,因为这是append出来的一个新的数组。

Copy

  1. 长度短的数组 copy 长度长的数组
func main() {
s1 := []int{1, 2, 3, 4}
s2 := []int{7, 8, 9}
copy(s1, s2) // s1是copy到的切片,s2被copy的数组,s2的长度为3,那么s1的前三位就会被从s2 copy过来的值给覆盖掉
fmt.Println(s1, s2)
}

打印结果如下:

[7 8 9 4] [7 8 9]

很显然,那你可以发现s1的前三位就会被从s2 copy过来的值给覆盖掉.

  1. 长度长的数组 copy 长度短的数组
func main() {
s1 := []int{1, 2, 3, 4, 5, 6}
s2 := []int{7, 8, 9}
copy(s2, s1)
fmt.Println(s1, s2)
}

打印结果如下:

[1 2 3 4 5 6] [1 2 3]

很显然,你可发现s2的长度依旧是三位,并不能把s1完完整整的复制过去。

  1. copy的高级用法-指定数组下标进行copy

    在copy的时候,我们可以使用copy去指定数组下标来copy,代码例子如下:
func main() {
s1 := []int{1, 2, 3, 4, 5, 6}
s2 := []int{7, 8, 9, 11, 12, 13}
copy(s2[4:], s1[2:4])
fmt.Println(s1, s2)
}

如何打印某个数组的所有元素

我们有下面三个方法请看代码:

func main() {
s1 := []int{1, 2, 3, 4, 5}
s2 := s1[:] // 方法1
s3 := s1[0:] // 方法2
s4 := s1[:len(s1)] // 方法3
fmt.Println(s2, s3, s4)
}

7 切片slice的更多相关文章

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

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

  2. golang切片slice

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

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

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

  4. Golang 入门 : 切片(slice)

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

  5. Go 灵活多变的切片Slice

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

  6. go递归函数如何传递数组切片slice

    数组切片slice这个东西看起来很美好,真正用起来会发现有诸多的不爽. 第一,数组.数组切片混淆不清,使用方式完全一样,有时候一些特性又完全不一样,搞不清原理很容易误使用. 第二,数组切片的appen ...

  7. [PY3]——内置数据结构(9)——线性结构与切片/命名切片slice()

    线性结构的总结 列表list  元组tuple  字符串str  bytes  bytearray的共同点: 都是顺序存储.顺序访问的: 都是可迭代对象: 都可以通过索引访问 线性结构的特征: 可迭代 ...

  8. Go语言【第十二篇】:Go数据结构之:切片(Slice)、范围(Range)、集合(Map)

    Go语言切片(Slice) Go语言切片是对数组的抽象,Go数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数 ...

  9. go中的数据结构切片-slice

    1.部分基本类型 go中的类型与c的相似,常用类型有一个特例:byte类型,即字节类型,长度为,默认值是0: bytes = []btye{'h', 'e', 'l', 'l', 'o'} 变量byt ...

随机推荐

  1. linux下修改tomcat使用的jdk版本

    遇到一种情况,就是linux上好像掉文件了,JDK的目录下没有了,具体问题还不清楚,不过要赶紧修复,不能影响其他程序的运行. 结构重新安装了JDK,tomcat还是启动失败,看l启动日志发现没找到还是 ...

  2. php多进程编程相关资料(以备参考)

    进程与线程的区别 要了解二者的区别与联系,首先得对进程与线程有一个宏观上的了解. 进程,是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竟争计算机系统资源的基本单位.每一个进程都 ...

  3. [设备]Linux设备是否可以被多个进程或者线程同时Open?

    当然可以 只要底层driver没有对重复打开做特殊处理,一般都可以被两个进程open 那当两个进程同时打开一个设备,当此设备收到数据时,怎么能保证每个进程都能收到数据?

  4. Drupal Nginx伪静态设置方法

    location ~ ^.*/files\/styles\/.*$ { access_log off; expires 45d; error_page @drupal; } location @dru ...

  5. EF5.x Code First 一对多关联条件查询,Contains,Any,All

    背景 通过多个部门id获取所有用户,部门和用户是多对多. 已知部门id,获取该部门包括该部门下的所有子部门的所有用户. 关系如下: public class Entity:IEntity { publ ...

  6. Android设计 - 图标设计概述(Iconography)

    2014-10-30 张云飞VIR 翻译自:https://developer.android.com/design/style/iconography.html Iconography 图标设计概述 ...

  7. SSM Spring +SpringMVC+Mybatis 整合配置 及pom.xml

    SSM Spring +SpringMVC+Mybatis 配置 及pom.xml SSM框架(spring+springMVC+Mybatis) pom.xml文件 maven下的ssm整合配置步骤

  8. kd-tree理论以及在PCL 中的代码的实现

    (小技巧记录:博客园编辑的网页界面变小了使用Ctrl  ++来变大网页字体) 通过雷达,激光扫描,立体摄像机等三维测量设备获取的点云数据,具有数据量大,分布不均匀等特点,作为三维领域中一个重要的数据来 ...

  9. Android开发-新建线程崩溃

    一直不满意车机不能实现屏保,最近发现可以通过设置亮度实现,顾萌生了自己写程序的来实现的念头,遂修改原来练手的app.毕竟过去了1年,各类程序.sdk都已经更新了不知道多少版本.经历了痛苦的升级.更新, ...

  10. [hbase] 查询数据

    获取hbase数据 说说:count 'SOCIA:T_SOCIA_ALBUM_TALK'scan 'SOCIA:T_SOCIA_ALBUM_TALK',{LIMIT=>5}get 'SOCIA ...