源地址 https://tour.go-zh.org/moretypes/11

一、描述

切片拥有 长度 和 容量

切片的长度就是它所包含的元素个数。

切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。

切片 s 的长度和容量可通过表达式 len(s) 和 cap(s) 来获取。

你可以通过重新切片来扩展一个切片,给它提供足够的容量。试着修改示例程序中的切片操作,向外扩展它的容量,看看会发生什么。

二、程序运行过程

1,第一个输出为[2,3,5,7,11,13],长度为6,容量为6;

2,左指针和右指针同时指向s[0],所以长度为0,容量为0;

3,左指针指向s[0],右指针指向s[4],由于切片概念是只包含左边元素不包含右边元素,所以长度为4,但左指针在s[0]处,走过0个元素,所以容量仍然为6;

4,在经历步骤3切片后的基础上,左指针指向s[2],右指针指向最右边,所以长度为2,由于左指针走过两个元素,离最右边还剩4个元素,所以容量为4。

三、小结

本文内容最难理解的是切片的容量,我们可以把容量当做成总长度减去左指针走过的元素值,比如:

s[:0] ——> cap = 6 - 0 =6;

s[2:] ——> cap = 6 - 2 = 4。

四、append() 和 copy() 函数

如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。

下面的代码描述了从拷贝切片的 copy 方法和向切片追加新元素的 append 方法。

package main

import "fmt"

func main() {
var numbers []int
printSlice(numbers) /* 允许追加空切片 */
numbers = append(numbers, )
printSlice(numbers) /* 向切片添加一个元素 */
numbers = append(numbers, )
printSlice(numbers) /* 同时添加多个元素 */
numbers = append(numbers, ,,)
printSlice(numbers) /* 创建切片 numbers1 是之前切片的两倍容量*/
numbers1 := make([]int, len(numbers), (cap(numbers))*) /* 拷贝 numbers 的内容到 numbers1 */
copy(numbers1,numbers)
printSlice(numbers1)
} func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

这时我将第18行要增加的元素改为五个,我们可以看到len=7,cap=8

再进行举例说明

新建切片并在里面追加元素

整体过程说明

  1. 创建numbers时,由于里面没有加入任何元素,所以len=0 cap=0 slice=[]
  2. append(numbers, 0)时,向空切片numbers中追加了一个元素,所以len=1 cap=1 slice=[0]
  3. append(numbers, 1)时,向之前的切片numbers中追加了一个元素,按Slice扩容机制,cap翻倍后=2,所以len=2 cap=2 slice=[0 1]
  4. append(numbers, 2,3,4,)时,向之前的切片numbers中追加了三个元素,按Slice扩容机制,cap翻倍后2*3=6,所以len=5 cap=6 slice=[0 1 2 3 4]
  5. append(numbers, 5,6,7,8,9,10)时,向之前的切片numbers中追加了六个元素,按Slice扩容机制,cap翻倍后6*2=12,所以len=11 cap=12 slice=[0 1 2 3 4 5 6 7 8 9 10]
  6. 新建切片numbers2 := append(numbers,11)时,是像之前的切片numbers追加一个元素11,追加后长度为12,容量为12,所以不需要扩容,len=12 cap=12 slice=[0 1 2 3 4 5 6 7 8 9 10 11]
  7. 新建切片numbers3 := append(numbers,12)时,是像之前的切片numbers追加一个元素12,追加后长度为12,容量为12,所以不需要扩容,len=12 cap=12 slice=[0 1 2 3 4 5 6 7 8 9 10 12]
  8. 创建切片numbers1时,由于cap(numbers)*2,所以容量要翻倍,len=11 cap=24 slice=[0 1 2 3 4 5 6 7 8 9 10]

五、总结

由此可知,容量随着底层数组长度的变化而不断变化,如果底层数组长度为4,在添加了一个元素后变成5,则容量变为 4*2=8,如果len=12,cap=12,如果追加一个元素后,那么新的cap=2*7=14。

(切片这块很神奇,我也只是把我遇到的总结下,如果有不足之处希望大家及时提出来,我好及时更新!)

六、参考资料

Golang中Slice的append详解

Go指南_切片的长度与容量的更多相关文章

  1. Go的切片:长度和容量

    虽然说 Go 的语法在很大程度上和 PHP 很像,但 PHP 中却是没有"切片"这个概念的,在学习的过程中也遇到了一些困惑,遂做此笔记. 困惑1:使用 append 函数为切片追加 ...

  2. Go指南练习_切片

    源地址 https://tour.go-zh.org/moretypes/18 一.练习题描述 实现 Pic.它应当返回一个长度为 dy 的切片,其中每个元素是一个长度为 dx,元素类型为 uint8 ...

  3. go基础_切片

    切片创建方式 1.通过数组创建 2.通过内置函数make创建 切片允许的操作 1.追加元素 2.通过内置函数make创建 package main import "fmt" fun ...

  4. Go语言 切片长度和容量

    package main import "fmt" func main() { s := []int{2, 3, 5, 7, 11, 13} printSlice(s) // Sl ...

  5. 『TensorFlow』张量拼接_调整维度_切片

    1.tf.concat tf.concat的作用主要是将向量按指定维连起来,其余维度不变:而1.0版本以后,函数的用法变成: t1 = [[1, 2, 3], [4, 5, 6]] t2 = [[7, ...

  6. go语言指南之切片练习

    题目: 实现 Pic.它应当返回一个长度为 dy 的切片,其中每个元素是一个长度为 dx,元素类型为 uint8 的切片.当你运行此程序时,它会将每个整数解释为灰度值(好吧,其实是蓝度值)并显示它所对 ...

  7. 2.9高级变量类型操作(列表 * 元组 * 字典 * 字符串)_内置函数_切片_运算符_for循环

    高级变量类型 目标 列表 元组 字典 字符串 公共方法 变量高级 知识点回顾 Python 中数据类型可以分为 数字型 和 非数字型 数字型 整型 (int) 浮点型(float) 布尔型(bool) ...

  8. Hive编程指南_学习笔记01

    第四章: HQl的数据定义 1:创建数据库   create database financials;   create database  if not exists financials; 2: ...

  9. Python笔记(九)_切片、列表生成式

    切片 mylist[:3] 取前3位元素,0可省略不写 mylist[-4:] 取后4位元素,0可省略不写 mylist[2:4] 从第2个开始取,取到第4个,但第4个不取,取的元素值为4-2=2 m ...

随机推荐

  1. SolidWorks知识积累系列-01

    Solidworks学习 1. 基本知识点总结 基准视图 主视图:从前往后看,前视基准 俯视图:从上往下看,上视基准 侧视图:从右向左看,右视基准 草图要求 单封闭性,草图要依附于某个位置 绘制大概形 ...

  2. 潭州课堂25班:Ph201805201 并发(进程,线程) 第十一课 (课堂笔记)

    线程,进程,是实现并发的方法, 并行: 在同一时刻,同时运行多个任务,CPU 的数量大于等于任务数量, 并发: 在同一时间间隔内, 同时处理多个任务, 并行是并发. 进程:表示一个正在执行的程序, 操 ...

  3. [CF521D]Shop

    [CF521D]Shop 题目大意: 你有一个长度为\(k(k\le10^5)\)的数列\(A_{1\sim k}\),有\(n(n\le10^5)\)种操作,操作包含以下\(3\)种: 将\(A_x ...

  4. C++ 类模板基础知识

    类模板与模板类 为什么要引入类模板:类模板是对一批仅仅成员数据类型不同的类的抽象,程序员只要为这一批类所组成的整个类家族创建一个类模板,给出一套程序代码,就可以用来生成多种具体的类,(这类可以看作是类 ...

  5. 我的git笔记

    转眼间加入git的阵营已经快两年了,结识git,缘起github,2年前在寻找代码托管网站,当时还是用svn,起初使用google code,可是google的服务虽好,在天朝你懂得,后来发现了git ...

  6. bzoj 3924 点分

    感谢asm.Definer清楚明了的题解: http://www.cnblogs.com/Asm-Definer/p/4470112.html 收获: 1.  关于重心, 对于一个无向图, 我们这样给 ...

  7. 429. N叉树的层序遍历

    429. N叉树的层序遍历 题意 给定一个 N 叉树,返回其节点值的层序遍历. (即从左到右,逐层遍历). 解题思路 和二叉树的层次遍历的思想一样: 实现 class Solution(object) ...

  8. linux中内存超出后可以这样

    http://www.cnblogs.com/hongten/archive/2012/11/16/java_PermGen_space.html

  9. AngualrJS中每次$http请求时的一个遮罩层Directive

    在AngualrJS中使用$http每次向远程API发送请求,等待响应,这中间有些许的等待过程.如何优雅地处理这个等待过程呢? 如果我们在等待过程中弹出一个遮罩层,会是一个比较优雅的做法. 这就涉及到 ...

  10. android: 发送自定义广播

    5.3.1    发送标准广播 在发送广播之前,我们还是需要先定义一个广播接收器来准备接收此广播才行,不然发 出去也是白发.因此新建一个 MyBroadcastReceiver 继承自 Broadca ...