Golang slice

yongsean  作者

2017.02.17 00:07  打开App

创建切片,len、cap、append

b := make([]int, 5)

println(len(b), cap(b)) // 输出结果是:5, 5

fmt.Println(b) // 输出结果是:[0 0 0 0 0]

上述代码是生成默认占用5个0值的切片,下面的输出结果是另一回事

b := make([]int, 0, 5)

println(len(b), cap(b)) // 输出结果是:0, 5

fmt.Println(b) // 输出结果是:[]

上述代码是生成cap长度为5,实际使用长度为0的切片,在指定的cap内进行append操作,是不会发生内存拷贝扩容操作。

b := make([]int, 0, 2)

fmt.Printf("%d, %d, %p\n", len(b), cap(b), b) // 0, 2, 0xc420012190

b = append(b, 1)

b = append(b, 2)

fmt.Printf("%d, %d, %p\n", len(b), cap(b), b) // 2, 2, 0xc420012190

b = append(b, 3)

fmt.Printf("%d, %d, %p\n", len(b), cap(b), b) // 3, 4, 0xc420012198

最后一行输出显示,内存地址跟前2次输出的不一样,并且cap值也在原来的基础上,翻了一倍,相当于做了如下操作:

// mock append

tmp := make([]int, 0, cap(b) * 2) // 是当前的cap值的翻倍

// 复制操作略过。。。

b = tmp

copy

正常的切片copy操作

a := make([]int, 5)

a[0] = 1

a[1] = 2

fmt.Println(a) // [1 2 0 0 0]

b := make([]int, 5)

b[0] = 11

b[1] = 22

b[2] = 33

b[3] = 44

b[4] = 55

fmt.Println(b) // [11 22 33 44 55]

copy(b, a)

fmt.Println(b) // [1 2 0 0 0]

另一个效果

a := make([]int, 5)

a[0] = 1

a[1] = 2

fmt.Println(a) // [1 2 0 0 0]

b := make([]int, 0, 5) // len(b)!=cap(b)

b = append(b, 11)

b = append(b, 22)

fmt.Println(b) // [11, 22]

copy(b, a)

fmt.Println(b) // [1 2]

第三行的输出,只是[1 2],不是[1 2 0 0 0],是对b切片里len(b)长度内的元素进行对应下标复制操作,假如len(b)==0,那输出结果是[]。 这是需要小心的地方,老司机会一不留神搞错,不了解的人那就更难说。

切片的切片

a := make([]int, 5)

a[0] = 1

a[1] = 2

a[2] = 3

a[3] = 4

a[4] = 5

// 原始数据输出

fmt.Printf("%v, %p\n", a, a) // [1 2 3 4 5], 0xc4200141b0

aslice1 := a[1:]

// 第一组输出

fmt.Printf("%v, %p\n", aslice1, aslice1) // [2 3 4 5], 0xc4200141b8

fmt.Println(len(aslice1), cap(aslice1)) // 4 4

aslice2 := a[1:3]

// 第二组输出

fmt.Printf("%v, %p\n", aslice2, aslice2) // [2 3], 0xc4200141b8

fmt.Println(len(aslice2), cap(aslice2)) // 2 4

aslice3 := a[:3]

// 第三组输出

fmt.Printf("%v, %p\n", aslice3, aslice3) // [1 2 3], 0xc4200141b0

fmt.Println(len(aslice3), cap(aslice3)) // 3 5

上面几组输出,粗看没什么,细看还是有值得注意的

每组的len和cap值都不太一样

切片的内存地址不是完全相同

len的值好理解,无异议。

cap的值:

在 第一组输出 中是4,是新切片首地址到原始切片尾地址的个数。

在 第二组输出 中也是4,是新切片首地址到原始切片尾地址的个数

在 第三组输出 中是5,道理如上

内存地址:

原始数据输出的地址和第三组输出的地址一样

第一组输出的地址和第二组输出的地址一样

这样输出的原因是,指向的切片首地址一样。在64位操作系统,int类型占8个字节,第二组输出的地址比第三组输出的地址多8个数值。若有新的切片是如下定义:

aslice4 := a[2:]

fmt.Println("%p\n", aslice4) // 0xc4200141c0

那输出结果是:0xc4200141c0,是 0xc4200141b8+8 的结果

go语言slice的理解的更多相关文章

  1. Java语言的个人理解

    Java语言的个人理解(比价深层次吧) 大四的生活确实十分的奢靡,不锻炼,不读书,几乎就是当一天和尚撞一天钟的生活,太颓废了,还好自己不是这个样子,不过身体确实差了很多,昨天跑了一圈内环(4KM),今 ...

  2. go语言---slice

    go语言---slice https://blog.csdn.net/cyk2396/article/details/78893420 一.数组切片的使用: //1.基于数组创建数组切片 var ar ...

  3. Go语言Slice作为函数参数详解

    Go语言Slice作为函数参数详解 前言 首先要明确Go语言中实质只有值传递,引用传递和指针传递是相对于参数类型来说. 个人认为上诉的结论不对,把引用类型看做对指针的封装,一般封装为结构体,结构体是值 ...

  4. C 语言指针怎么理解?

    对于程序员来说内存可以简化成这样一种东西:<img src="https://pic1.zhimg.com/4d060c3f67c22cd4b07273db00f64708_b ...

  5. 说说对C语言指针的理解

    指针困扰了一些学习编程的人,或许你的老师会告诉你,指针比较难理解. 我当时被老师的话唬住所以学习指针那章的时候都没心情听课.(说得像讲别的内容时我听了似的,开玩笑) 导致了学习链表的时候各种卧槽. * ...

  6. C语言数据类型的理解

    数据类型的定义: 作为一种语言,必然有所谓的语言组成要素,就像日常生活中人们之间的交流一样,首先会有字,字再成词组,再来就是句子,后来呢就是段落等等.当然不同的字,词,句这些在一起,就会有不同的表达效 ...

  7. GO语言slice详解(结合源码)

    一.GO语言中slice的定义 slice 是一种结构体类型,在源码中的定义为: src/runtime/slice.go type slice struct { array unsafe.Point ...

  8. 由linux内核某个片段(container_of)引发的对于C语言的深入理解

    /usr/src/linux-source-3.8.0/drivers/gpu/drm/radeon 这个文件夹以下 去找到这个文件 mkregtable.c  打开,就能够看到了. #define ...

  9. 有关C++ std::string 类的类型转换 其他语言永远无法理解的伤

    最近做了个项目,C++的MFC窗口程序,一个基于dialog的学生-图书管理系统,有一些感触,最后会放上一些项目截图和部分代码提供大家参考.如果有什么好方法和建议欢迎指导. 强类型,为什么这么伤 我知 ...

随机推荐

  1. 常见Z纯CSS小样式合集(三角形)

    三角形 .sanjiao{ width:0px; height: 0px; overflow: hidden; border-width: 100px; border-color: transpare ...

  2. UNICODE本地编译freescale的i.MX6Q的android4.2.2&android4.4.2 && 全志a80的步骤x1

    20151031本地编译freescale的i.MX6Q的android4.2.2&android4.4.2 && 全志a80的步骤x1 2015/10/31 15:07 开始 ...

  3. Android RecyclerView局部刷新那个坑

    关键:public final void notifyItemChanged(int position, Object payload) RecyclerView局部刷新大家都遇到过,有时候还说会遇见 ...

  4. CAD得到布局名

    js代码如下: var database = mxOcx.GetDatabase(); var sRet = null; //返回数据库中的布局字典 var spLayoutDictionary = ...

  5. CAD得到指定条件的实体

    主要用到函数说明: IMxDrawSelectionSet::Select2 构造选择集.详细说明如下: 参数 说明 [in] MCAD_McSelect Mode 构造选择集方式 [in] VARI ...

  6. BZOJ 1058: [ZJOI2007]报表统计 multiset + 卡常

    Code: #include<bits/stdc++.h> #define maxn 600000 #define inf 1000000000 using namespace std; ...

  7. HTTP服务和APACHE

    HTTP服务和APACHE 1. 跨Internet的主机间通讯 要通过Internet进行通信,至少需要一对套接字:其中一个运行在客户端,定义了一个唯一的客户进程,称之为ClientSocket,另 ...

  8. 验证DNS解析失败:解决办法之一

    今天晚上练习简单的DNS解析验证: 环境是在一台虚拟机上搭建,另一台虚拟机验证,步骤如下: 虚拟机A: 1.安装软件包 bind  和bind-chroot[root@svr7 ~]# yum -y ...

  9. 爬虫-----HTML解析

    对HTML的解析: 在解析复杂的HTML的页面时,需要避免一些问题,好让爬虫工作变得得心应手. • 寻找“打印此页”的链接,或者看看网站有没有HTML样式更友好的移动版(把自己 的请求头设置成处于移动 ...

  10. [bzoj2461][BeiJing2011][符环] (括号配对+记忆化搜索+高维dp)

    Description 在可以炼制魔力强大的法杖的同时,Magic Land 上的人们渐渐意识到,魔力强大并不一定能给人们带来好处——反而,由此产生的破坏性的高魔力释放,给整个大陆蒙上了恐怖的阴影.  ...