Slice的本质

Slice的本质

我们先看下面的代码,看看它的输出是什么:

package mainimport "fmt"type Slice []intfunc (A Slice) Append(value int) {A = append(A, value)
}
func main() {mSlice := make(Slice, 10, 20)mSlice.Append(5)fmt.Println(mSlice)
}
//output: [0 0 0 0 0 0 0 0 0 0]

我们查看append()前后变量的地址值:

func (A Slice) Append(value int) {A1 := append(A, value)fmt.Printf("&A = %p &A1 = %p\n", A, A1)
} 
//output: &A = 0xc000114000 &A1 = 0xc000114000

所以说append()之后返回的Slice,是不是原来的Slice

其实,我们在make一个Slice的时候可以传递三个参数:数据、长度和容量,这里就要提到SliceHeader

SliceHeaderSlice运行时的具体表现,它的结构定义如下:

type SliceHeader struct {Data uintptr     //指向底层数据源数组Len intCap int
}

那么我们可以将Slice转换为SliceHeader,再来看看A和A1内部的值是否一致。

func (A Slice) Append(value int) {A1 := append(A, value)sh := (*reflect.SliceHeader)(unsafe.Pointer(&A))fmt.Printf("A Data:%d,Len:%d,Cap:%d\n", sh.Data, sh.Len, sh.Cap)sh1 := (*reflect.SliceHeader)(unsafe.Pointer(&A1))fmt.Printf("A1 Data:%d,Len:%d,Cap:%d\n", sh1.Data, sh1.Len, sh1.Cap)
}
//output: A Data:824634474496,Len:10,Cap:20
//        A1 Data:824634474496,Len:11,Cap:20

会发现它们的Len是不一样的,所以不是同一个Slice,因此使用append()并没有改变原来的A,而是生成了一个新的A1A只在Append()内有效,mSlice并没有发生改变。这里正确的做法是让Append()返回append()之后的结果。

Append returns the updated slice. It is therefore necessary to store the result of append

上面的例子中,设置的Len是10和 Cap 是20,Cap足够大,所以内置的append()并没有生成新的底层数组。

mSlice := make(Slice, 10, 10)

再运行后发现两个SliceData不再一样:

//output: A Data:824633852064,Len:10,Cap:10
//        A1 Data:824634187776,Len:11,Cap:20

这是因为在append()的时候,发现Cap不够,生成了一个新的Data数组,用于存储新的数据,并且同时扩充了Cap容量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309636.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你需要了解操作系统发展历程

本文我们大概回顾计算机操作系统发展历程,这里不会记录关于操作系统的完整历史记录,只是记录那些里程碑事件,看看各位接触计算机时,操作系统发展正处于哪个年代起初没有操作系统,没有编程语言或编译器,甚至…

[汇编语言]实验:更灵活的寻址方式 -应用si和di

实验内容: (1) 用寄存器SI和DI实现将字符串‘welcome to masm!’ 复制到它后面的数据区中。 (2) 用[bx(si或di)idata]的方式,来使程序变得简洁。 (1) 代码如下: assume ds:datasg,cs:code…

http.ListenAndServe()到底做了什么?

参考:https://studygolang.com/articles/25849?frsidebar ​ http://blog.csdn.net/gophers 实现一个最简短的hello world服务器 package mainimport "net/http"func main() {http.HandleFunc("/", func(w http.ResponseWriter, r *http.Reque…

Strongly connected HDU - 4635(tarjan+强连通分量)

题意: 给一个简单有向图,让你加最多的边,使他还是一个简单有向图。 题目: Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the edges you can add that the graph is still a …

C++编程基础题训练

1.编写一个c风格的程序&#xff0c;用动态分配空间的方法计算Fibonacci数列的前20项并存储到动态分配的空间中 1.代码如下 #include <iostream> using namespace std;int main() {int *a new int[25];a[0] 0;a[1] 1;for (int i 2; i < 20; i){a[i] a[i - 1] a…

基于 abp vNext 和 .NET Core 开发博客项目 - 使用Redis缓存数据

上一篇文章完成了项目的全局异常处理和日志记录。在日志记录中使用的静态方法有人指出写法不是很优雅&#xff0c;遂优化一下上一篇中日志记录的方法&#xff0c;具体操作如下&#xff1a;在.ToolKits层中新建扩展方法Log4NetExtensions.cs。//Log4NetExtensions.cs using log4…

G - 水陆距离 HihoCoder - 1478(广搜+队列先进先出性质)

题目&#xff1a; 给定一个N x M的01矩阵&#xff0c;其中1表示陆地&#xff0c;0表示水域。对于每一个位置&#xff0c;求出它距离最近的水域的距离是多少。 矩阵中每个位置与它上下左右相邻的格子距离为1。 Input 第一行包含两个整数&#xff0c;N和M。 以下N行每行M个0…

第一讲 工作区和GOPATH

此为 《极客时间&Go语言核心36讲》 个人笔记&#xff0c;具体课程详见极客时间官网。 Table of Contents generated with DocToc 第一讲 工作区和GOPATH 1. 环境变量配置2. 配置GOPATH的意义 2.1 Go语言源码的组织方式2.2 源码安装后的结果&#xff08;归档文件、可执行文…

C++重载运算符小结与注意点

重载运算符需注意: 1.重载运算符时容易忘记写返回值。 2.重载赋值运算符时&#xff0c;记得加const&#xff0c;因为赋值操作必须是固定的右值。 3重载时&#xff0c;写在类中的只能有一个参数(实际有两个参数&#xff0c;另外一个是this指针&#xff0c;我们看不见而已)&am…

开发大会上,前微软CEO放出的狠话!.NET开发随时起飞,你准备好了吗?

“开发者&#xff0c;开发者&#xff0c;开发者&#xff0c;开发者”&#xff0c;微软前任CEO史蒂夫鲍尔默(Steve Ballmer)用这种略带疯狂、又唱又跳的方式表达他对开发者的热爱。不夸张的说&#xff0c;相比二十年前那个如日中天的巨无霸微软&#xff0c;现在的微软比以往任何…

Balanced Lineup POJ - 3264(线段树模板+查询比大小+建树)

题意&#xff1a; 给你n个数&#xff0c;然后问一段区间的最大的差值是多少。 题目&#xff1a; For the daily milking, Farmer John’s N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbe…

第二讲 命令源码文件

此为 《极客时间&Go语言核心36讲》 个人笔记&#xff0c;具体课程详见极客时间官网。 Table of Contents generated with DocToc 第二讲 命令源码文件 1. 什么是命令源码文件&#xff1f;2. 命令参数的接收和解析 2.1 命令源码文件怎么接收参数?2.2 怎样在运行源代码文件…

程序员过关斩将--为微服务撸一个简约而不简单的配置中心

点击上方蓝字 关注我们毫不犹豫的说&#xff0c;现代高速发展的互联网造就了一批又一批的网络红人&#xff0c;这一批批网红又极大的催生了特定平台的一大波流量&#xff0c;但是留给了程序员却是一地鸡毛&#xff0c;无论是运维还是开发&#xff0c;每天都会担心服务器崩溃&a…

Just a Hook HDU - 1698(查询区间求和+最基础模板)

题意&#xff1a; 给你一个1~n的区间&#xff0c;起始区间内均为1&#xff0c;然后对子区间进行值更新&#xff0c;最后求区间和。 题目&#xff1a; In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. The hook is ma…

DDIA笔记——数据复制

Table of Contents generated with DocToc 此篇为《数据密集型应用系统设计》&#xff08;DDIA&#xff09;读书笔记&#xff0c;笔记可能存在遗漏&#xff0c;建议直接阅读原书。 第五章 数据复制 主从复制 复制滞后复制滞后带来的问题 多主节点复制 适用场景处理写冲突拓扑结…

基于 abp vNext 和 .NET Core 开发博客项目 - 集成Hangfire实现定时任务处理

上一篇文章成功使用了Redis缓存数据&#xff0c;大大提高博客的响应性能。接下来&#xff0c;将完成一个任务调度中心&#xff0c;关于定时任务有多种处理方式&#xff0c;如果你的需求比较简单&#xff0c;比如就是单纯的过多少时间循环执行某个操作&#xff0c;可以直接使用.…

Docker基本组成 和 基本命令

此篇为Docker笔记&#xff0c;文章可能存在疏忽&#xff0c;建议直接观看原视频。 视频地址&#xff1a;https://www.bilibili.com/video/BV1og4y1q7M4?spm_id_from333.999.0.0 Docker基本组成 和 基本命令 镜像 image&#xff1a;就好比一个模板&#xff0c;可以通过这个模板…

Assign the task HDU - 3974(线段树+dfs建树+单点查询+区间修改)

题意&#xff1a; 染色问题&#xff1a;给一个固定结构的树&#xff0c;现在有两个操作&#xff1a; &#xff08;1&#xff09; y 将结点x及其所有后代结点染成颜色y&#xff1b; &#xff08;2&#xff09;查询结点x当前的颜色。 其实就是区间染色问题&#xff0c;不过需要d…