go语言slice的理解

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 的结果

时间: 2024-10-11 16:53:27

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

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

最近做了个项目,C++的MFC窗口程序,一个基于dialog的学生-图书管理系统,有一些感触,最后会放上一些项目截图和部分代码提供大家参考.如果有什么好方法和建议欢迎指导. 强类型,为什么这么伤 我知道强类型是很必要的,但是最近使用的都是一些弱类型的语言,到回来使用C++的时候还真是很不习惯.std::string在学的时候就知道了,好用但还是跟c标准char[]有很大区别的,MFC编程中又加入了没有学过的Cstring和LPSTR.LPWSTR等,下面我就来分享一下一些有关类型转换的感受. 什

linux信号解释(4)--C语言下的理解

上一节中中简单介绍了信号的处理机制,就是调用函数库来实现信号的处理,因此,在这节中,介绍在C语言下如何理解信号的处理机制. 创建一个文件signal.c,文件内容如下:(对于学过一下C语言的童鞋来说是不是很熟悉呢) #include<signal.h> //信号函数库 #include<unistd.h> //C和C++语言提供对POSIX #include<stdio.h> //标准的输入输出库 void signalout(int signo) //自定义signa

go语言---slice

go语言---slice https://blog.csdn.net/cyk2396/article/details/78893420 一.数组切片的使用: //1.基于数组创建数组切片 var array [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} var sliceMy = array[1:7] //array[startIndex:endIndex] 不包含endIndex //2.直接创建数组切片 slice2 := make([]i

C语言数据类型的理解

数据类型的定义: 作为一种语言,必然有所谓的语言组成要素,就像日常生活中人们之间的交流一样,首先会有字,字再成词组,再来就是句子,后来呢就是段落等等.当然不同的字,词,句这些在一起,就会有不同的表达效果,这也就好理解为何C语言会有相应的数据类型了.c语言数据类型如下图: 所谓数据类型是按被定义变量的性质,表示形式,占据存储空间的多少,构造特点来划分的. 在C语言中,数据类型可分为:基本数据类型,构造数据类型,指针类型,空类型 数据类型的标示意义: 数据类型的所占的字节数可以这样理解,当我们写作文

C语言01深入理解基本概念(一)

基本数据类型分析 数据类型 什么是数据类型 ? ?  数据类型可以理解为固定内存大小的别名 ?  数据类型是创建变量的模子 类型的本质 char short int 1 byte 2 byte 4 byte 内存空间 char c short s int i 变量本质 ?  变量是一段实际连续存储空间的别名 ?  程序中通过变量来申请并命名存储空间 ?  通过变量的名字可以使用存储空间 auto,register,static 分析 auto ? C 语言中的变量可以有自己的属性 ?  在定义变

说说对C语言指针的理解

指针困扰了无数学习编程的人,或许你的老师会告诉你,指针比较难学. 然而,不要被吓到,本宝宝就是当时被老师的话唬住所以学习指针那章的时候都没心情听课.(说得像讲别的内容时我听了似的,just kidding) 导致了学习链表的时候各种卧槽. *************************** 基本介绍 ************************** 程序中数据的使用往往是以变量的形式出现,每个变量都对应若干存储单元,变量的值存储在存储单元中,通过对变量的引用和赋值就可以使用或修改存储在存

COM对象在易语言中的理解和使用

在windows编程中,会用到COM对象,那什么是COM对象呢?如果第一次接触,一定是不好理解这个概念的!我记得我第一次接触COM对象这个概念的时候,可以说是一头雾水! 什么是COM对象?下面是个人看了很多资料和实践所得到的理解: 一 com对象跟对象编程里面的对象概念应该是一样的,都是对象.竟然都是对象,那么一定都有属性和方法. 二 com对象,官方说法是组件对象模型(compoment object model),他是一组规范,是MicroSoft创建的一组二进制和网络标准,用于解决两个组件

C语言变量的理解

1.定义: 变量是一段有名字的连续存储空间.在源代码中通过定义变量来申请并命名这样的存储空间,并通过变量的名字来使用这段存储空间.下面,我们来理解怎样定义一个变量.例如去住酒店.第一步,前台登记:住几人间(数据类型): 第二步,取到房卡(标示的是房间的名字): 第三步,入住房间(得到相应的存储空间). 补充:常量可以看着是这个酒店的名字,你不可能随时去改酒店的名字吧.这是符合实际的,实际中也是符合相应的数据类型的. 2.定义格式: 数据类型 变量名 1,...,变量名n  :       int

C语言复杂指针理解

学习和使用C语言近十年了但对C语言的复杂指针依然有些迷糊索性花点时间分析一下,下面是一些心得,希望对读者有所帮助 取The C Programming Language中的两个例子以分析 char (*(*x())[])(); char (*(*x[3])())[5]; 若直接让我们说出这两个x分别是什么意思往往会有一些困难, 这里我们可以使用代入法(暂且叫代入法)来分析 分析结果转述原则: 左端=右端(比如下面的Y=*x()中Y为左端, *x()为右端) 若右端为数组则左端可被看作右端的其中一