切片(slice)可以看作一种对数组的包装形式,它包装的数组为该切片的底层数组。
反过来讲,切片是针对其底层数组中某个连续片段的描述,下面的代码声明了一个切片类型的变量:
var ips = []string{"192.168.1.1","192.168.1.2","192.168.1.3"}
与数组不同,切片的类型自变量(如[]string)并不携带长度信息。
切片的长度是可变的,且并不是类型的一部分;只要元素类型相同,两个切片的类型就是相同的。
此外,一个切片类型的零值总是nil,此零值的长度和容量都为0。

切片本身并非动态数组或数组指针。它内部通过指针引用底层数组,设定相关属性将数据读写操作限定在指定区域内。
其内部结构包含了3个元素:指向底层数组中某个元素的指针、切片的长度以及切片的容量。

type slice struct {
array unsafe.Pointer
len int
cap int
}

可基于数组或数组指针创建切片,以开始和结束索引位置确定所引用的数组片段。
不支持反向索引,实际范围是一个右半开区间。

package main

import "fmt"

func main() {
x := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println(x[:], len(x[:]), cap(x[:]))
fmt.Println(x[2:5], len(x[2:5]), cap(x[2:5]))
fmt.Println(x[2:5:7], len(x[2:5:7]), cap(x[2:5:7]))
fmt.Println(x[4:], len(x[4:]), cap(x[4:]))
fmt.Println(x[:4], len(x[:4]), cap(x[:4]))
fmt.Println(x[:4:6], len(x[:4:6]), cap(x[:4:6]))
} /*
len cap
x[:] [0 1 2 3 4 5 6 7 8 9] 10 10
x[2:5] [2 3 4] 3 8
x[2:5:7] [2 3 4] 3 5
x[4:] [4 5 6 7 8 9] 6 6
x[:4] [0 1 2 3] 4 10
x[:4:6] [0 1 2 3] 4 6
*/
//[x:y:z] x:切片的起始位置 y:切片的终止位置 z:容量的终止位置
//cap表示切片所引用数组片段的真实长度
//len用于限定可读的写元素数量

和数组一样,切片同样使用索引号访问元素内容。
起始索引为0,而非对应的底层数组和真实索引位置。

package main

import "fmt"

func main() {
x := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s := x[2:5] for i := 0; i < len(s); i++ {
fmt.Println(s[i])
}
} /*
2
3
4
*/

可直接创建切片对象,无需预先准备数组。
因为是引用类型,须使用make函数或显式初始化语句,它会自动完成底层数组内存分配。

package main

import "fmt"

func main() {
s1 := make([]int, 3, 5) //make(初始化类型,长度,容量) 如果没有指定容量则与长度一致
s2 := make([]int, 3)
s3 := []int{10, 20, 5: 30} //第6个元素为30 fmt.Println(s1, len(s1), cap(s1)) //[0 0 0] 3 5
fmt.Println(s2, len(s2), cap(s2)) //[0 0 0] 3 3
fmt.Println(s3, len(s3), cap(s3)) //[10 20 0 0 0 30] 6 6
}

注意下面两种定义方式。

package main

import "fmt"

func main() {
var a []int //仅定义了一个[]int变量,并未执行初始化操作
b := []int{} //初始化表达式完成了全部创建过程 fmt.Println(a == nil, b == nil) //true false
}

不支持比较操作,就算元素类型支持也不行,仅能判断是否为nil。
可获取元素地址,但不能像数组那样直接用指针访问元素内容。

如果元素类型也是切片,那么就可实现类似交错数组功能。

package main

import "fmt"

func main() {
x := [][]int{
{1, 2},
{10, 20, 30},
{100},
}
fmt.Println(x[1]) //取值 x[2] = append(x[2], 200, 300) //添加元素
fmt.Println(x)
} /*
[10 20 30]
[[1 2] [10 20 30] [100 200 300]]
*/

新建切片对象依旧指向原底层数组,也就是说修改对所有关联切片可见。
需要注意的是,当向新建切片中添加值的时候,并不会向底层数组中添加

package main

import "fmt"

func main() {
d := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s1 := d[3:7] //[3, 4, 5, 6]
s2 := s1[1:3] //[4, 5] for i := range s2 {
s2[i] += 100 //[104, 105]
}
fmt.Println(d)
fmt.Println(s1)
fmt.Println(s2)
} /*
[0 1 2 3 104 105 6 7 8 9]
[3 104 105 6]
[104 105]
*/

append向切片尾部添加数据,返回新的切片对象。

package main

import "fmt"

func main() {
s := make([]int, 0, 5) s1 := append(s, 10)
s2 := append(s1, 20, 30) fmt.Println(s, len(s), cap(s))
fmt.Println(s1, len(s1), cap(s1))
fmt.Println(s2, len(s2), cap(s2))
} /*
[] 0 5
[10] 1 5
[10 20 30] 3 5
*/

数组被追加到原底层数组。如果超出cap限制,则为新切片对象重新分配数组。

package main

import "fmt"

func main() {
s := make([]int, 0, 100)
s1 := s[:2:4]
s2 := append(s1, 1, 2, 3, 4, 5, 6) //超出是s1 cap限制,分配新底层数组 fmt.Println("s1:", &s1[0], s1)
fmt.Println("s2:", &s2[0], s2)
fmt.Println("s[:10]:", s[:10])
fmt.Printf("s1 cap: %d, s2 cap: %d\n", cap(s1), cap(s2))
} /*
s1: 0xc000088000 [0 0]
s2: 0xc00007e040 [0 0 1 2 3 4 5 6] //数组地址不同,确认新分配
s[:10]: [0 0 0 0 0 0 0 0 0 0] //append并未向原数组中写入数据
s1 cap: 4, s2 cap: 8 //新数组是原cap的2倍,一般是2倍,但也不绝对
*/

在两个切片数据间复制数据,允许指向同一底层数组,允许目标区间重叠。
最终所复制长度以较短的切片长度(len)为准。

package main

import "fmt"

func main() {
s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} s1 := s[5:8]
n := copy(s[4:], s1)
fmt.Println(n, s) s2 := make([]int, 6)
n = copy(s2, s)
fmt.Println(n, s2)
} /*
3 [0 1 2 3 5 6 7 7 8 9]
6 [0 1 2 3 5 6]
*/

go——切片的更多相关文章

  1. ArcGIS 10.0紧凑型切片读写方法

    首先介绍一下ArcGIS10.0的缓存机制: 切片方案 切片方案包括缓存的比例级别.切片尺寸和切片原点.这些属性定义缓存边界的存在位置,在某些客户端中叠加缓存时匹配这些属性十分重要.图像格式和抗锯齿等 ...

  2. 利用Python进行数据分析(5) NumPy基础: ndarray索引和切片

    概念理解 索引即通过一个无符号整数值获取数组里的值. 切片即对数组里某个片段的描述. 一维数组 一维数组的索引 一维数组的索引和Python列表的功能类似: 一维数组的切片 一维数组的切片语法格式为a ...

  3. 充电时间 Go中的数组、切片、map简单示例

    数组是固定长度的,依稀让我想起了VB:切片是动态的:map一般是键值对 package main import ( "fmt" ) func main() { var userna ...

  4. GO语言总结(3)——数组和切片

    上篇博文简单介绍了一下Go语言的基本类型——GO语言总结(2)——基本类型,本篇博文开始介绍Go语言的数组和切片. 一.数组 与其他大多数语言类似,Go语言的数组也是一个元素类型相同的定长的序列. ( ...

  5. [LeetCode] Arithmetic Slices 算数切片

    A sequence of number is called arithmetic if it consists of at least three elements and if the diffe ...

  6. 网络切片在5G中的应用

    SDNLAB君 • 16-11-25 •1509 人围观 5G和网络切片 当5G被广泛提及的时候,网络切片是其中讨论最多的技术.像KT.SK Telecom.China Mobile.DT.KDDI. ...

  7. KRPano资源分析工具使用说明(KRPano XML/JS解密 切片图批量下载 球面图还原 加密混淆JS还原美化)

    软件交流群:571171251(软件免费版本在群内提供) krpano技术交流群:551278936(软件免费版本在群内提供) 最新博客地址:blog.turenlong.com 限时下载地址:htt ...

  8. 使用KRPano资源分析工具强力加密KRPano项目(XML防破解,切片图保护,JS反调试)

    软件交流群:571171251(软件免费版本在群内提供) krpano技术交流群:551278936(软件免费版本在群内提供) 最新博客地址:blog.turenlong.com 限时下载地址:htt ...

  9. 使用KRPano资源分析工具一键下载全景网站切片图

    软件交流群:571171251(软件免费版本在群内提供) krpano技术交流群:551278936(软件免费版本在群内提供) 最新博客地址:blog.turenlong.com 限时下载地址:htt ...

  10. 窥探Swift之数组安全索引与数组切片

    今天是元宵节,祝大家元宵节快乐!在Swift中的数组和字典中下标是非常常见的,数组可以通过索引下标进行元素的查询,字典可以通过键下标来获取相应的值.在使用数组时,一个常见的致命错误就是数组越界.如果在 ...

随机推荐

  1. 海康威视监控设备的Yv12视频在XNA框架中播放

    最近使用海康威视的5寸一体化智能球,查阅些SDK, 在Winform中海康威视能较好的集成,但是对于Yv12编解码和实时视频流的支持未找到较好的SDK介绍. 因为项目需要是用在XNA游戏框架中,本身有 ...

  2. Linux压缩解压缩命令学习笔记

    Linux中主要的压缩文件有:*.gz   *.tar  *.tar.gz  *.zip  *.bz2  *.tar.bz2 .zip这种古老的压缩格式,在window和Linux中都不需要安装软件可 ...

  3. [转]用了docker是否还有必要使用openstack?

    从一项颠覆性的技术成果转化并衍生出一整套社区体系,Docker在发展速度上打破了一个又一个历史纪录.然而,Docker项目在采纳与普及方面表现出惊人态势的同时,也给我们带来了一系列疑问与困惑. 在今天 ...

  4. Hive学习笔记——HQL用法及UDF,Transform

    Hive中没有定义专门的数据格式,数据格式可以由用户指定,用户定义数据格式需要指定三个属性:列分隔符(通常为空格.”\t”.”\x001″).行分隔符 (”\n”)以及读取文件数据的方法(Hive 中 ...

  5. 【转】redis C接口hiredis 简单函数使用介绍

    from : http://blog.csdn.net/kingqizhou/article/details/8104693 hiredis是redis数据库的C接口,目前只能在linux下使用,几个 ...

  6. VMWare虚拟机 网络连接模式

    这个是rocks 群里面我的一个朋友分享的,我觉很好而且描述的很清楚,这是一个做事的态度问题.   1 VMWare虚拟机bridged.host-only和NAT网络模式的区别和用法 VMWare提 ...

  7. [转]VMPlayer的Briged网络配置

    VMware.VMware Player.VirtualBox.Windows Virtual PC等虚拟机软件都提供了桥接(bridged).网络地址转换(network address trans ...

  8. redis php 实例一

    下面的例子都是基于php-redis这个扩展的. 1,connect 描述:实例连接到一个Redis. 参数:host: string,port: int 返回值:BOOL 成功返回:TRUE;失败返 ...

  9. FreeRTOS系列第17篇---FreeRTOS队列

    本文介绍队列的基本知识,具体源代码分析见<FreeRTOS高级篇5---FreeRTOS队列分析> 1.FreeRTOS队列 队列是基本的任务间通讯方式.能够在任务与任务间.中断和任务间传 ...

  10. (转)使用.NET Reflector 查看Unity引擎里面的DLL文件

    当你查看unity里面API的时候,是不是有时候追踪了一两步就碰到DLL文件走不下去了呢?很是不爽吧. 这种问题我也是经常碰到.这是人家商业引擎不想让你看到底层代码啦,所以着急不得. 不过,今天我终于 ...