7 切片slice
include
- 切片
- 切片的日常用法
切片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)
}
切片常用方法:
- 从某一位下标取到最后一位下标
- 从第一位下标到指定的某一位下标
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
- 长度短的数组 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过来的值给覆盖掉.
- 长度长的数组 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完完整整的复制过去。
- 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的更多相关文章
- go 数组(array)、切片(slice)、map、结构体(struct)
一 数组(array) go语言中的数组是固定长度的.使用前必须指定数组长度. go语言中数组是值类型.如果将数组赋值给另一个数组或者方法中参数使用都是复制一份,方法中使用可以使用指针传递地址. 声明 ...
- golang切片slice
切片slice是引用类型 len()函数获取元素的个数 cap()获取数组的容量 1.申明方式 (1)var a []int 与数组不同的是他不申明长度(2)s2 := make([]int, 3, ...
- 在python&numpy中切片(slice)
在python&numpy中切片(slice) 上文说到了,词频的统计在数据挖掘中使用的频率很高,而切片的操作同样是如此.在从文本文件或数据库中读取数据后,需要对数据进行预处理的操作.此时就 ...
- Golang 入门 : 切片(slice)
切片(slice)是 Golang 中一种比较特殊的数据结构,这种数据结构更便于使用和管理数据集合.切片是围绕动态数组的概念构建的,可以按需自动增长和缩小.切片的动态增长是通过内置函数 append( ...
- Go 灵活多变的切片Slice
我们知道数组定义好之后其长度就无法再修改,但是,在实际开发过程中,有时候我们并不知道需要多大的数组,我们期望数组的长度是可变的, 在 Go 中有一种数据结构切片(Slice) 解决了这个问题,它是可变 ...
- go递归函数如何传递数组切片slice
数组切片slice这个东西看起来很美好,真正用起来会发现有诸多的不爽. 第一,数组.数组切片混淆不清,使用方式完全一样,有时候一些特性又完全不一样,搞不清原理很容易误使用. 第二,数组切片的appen ...
- [PY3]——内置数据结构(9)——线性结构与切片/命名切片slice()
线性结构的总结 列表list 元组tuple 字符串str bytes bytearray的共同点: 都是顺序存储.顺序访问的: 都是可迭代对象: 都可以通过索引访问 线性结构的特征: 可迭代 ...
- Go语言【第十二篇】:Go数据结构之:切片(Slice)、范围(Range)、集合(Map)
Go语言切片(Slice) Go语言切片是对数组的抽象,Go数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数 ...
- go中的数据结构切片-slice
1.部分基本类型 go中的类型与c的相似,常用类型有一个特例:byte类型,即字节类型,长度为,默认值是0: bytes = []btye{'h', 'e', 'l', 'l', 'o'} 变量byt ...
随机推荐
- CentOS6.5 安装Python 的依赖包
1.CentOS6.5 安装Python 的依赖包 yum groupinstall "Development tools"yum install zlib-devel bzip2 ...
- 前端常用功能记录(二)—datatables表格(转)
前端常用功能记录(二)—datatables表格 并不是所有的后台开发都有美工和前端工程师来配合做页面,为了显示数据并有一定的美感,jQuery的DataTables插件对于像我这样的前端菜鸟来说真是 ...
- 从零写Java Web框架——实现Ioc依赖注入
大概思路 通过读取配置文件,获取框架要加载的包路径:base-package,类似于 Spring 配置文件中的: <context:component-scan base-package=&q ...
- Unity Shader学习资料
文本教程 http://www.cnblogs.com/polobymulberry/p/4314147.html 视频教程 http://www.sikiedu.com/my/course/37 冯 ...
- Functions: C++'s Programming Modules
在这一章中要学习以下内容: 函数基础 函数原型 通过value向函数传递参数 设计处理数组的函数 使用const指针参数 设计函数处理文本字符串 设计函数处理结构体 设计函数处理string类型的对象 ...
- 【进阶修炼】——改善C#程序质量(3)
32, 总是优先考虑泛型. 泛型代码有很好的重复利用性,和类型安全性. 33, 应尽量避免在泛型类中声明静态成员. 静态成员达不到共享的目的.List<int>和List<Strin ...
- android开发(37) android使用android_serialport_api 操作串口,解决权限问题
最近有个项目,要使用android设备操作串口的 斑马GK888T打印机,使用打印机打印二维码. 硬件设备连接方式: 安卓设备 通过 串口RS232 连接 斑马打印机的串口 那么就要解决:使用安卓设备 ...
- 【C】——网络编程-聊天室
功能介绍: 此demo是基于TCP套接字编程,目的是实现一个聊天室效果.类似于QQ群效果,如果上线可以通知其他好友,下线也会通知其他好友. 需要用的技术: 一.socket编程. 1> sock ...
- 使用JAAS登录kerberos服务器
java代码: package com.snsprj.jaas0822; import javax.security.auth.*; import javax.security.auth.callba ...
- 点击input 禁止手机自带键盘弹出
<input readonly data-field="date" placeholder="請選擇結束時間" class="start_t ...