slice+append陷阱

2023-11-17

1、前言

今天在网上看slice扩容原理,偶然看到一个slice的题目,感觉很有意思。题目如下:

package main

import "fmt"

func main() {
	s1 := []int{1, 2}
	s2 := s1
	s2 = append(s2, 3)
	Test1(s1)
	Test1(s2)
	fmt.Println(s1, s2)
}

func Test1(s []int) {
	s = append(s, 0)
	for i := range s {
		s[i]++
	}
}

选项如下:

A: [2,3] [2,3,4]
B: [1,2] [1,2,3]
C: [1,2] [2,3,4]
D: [2,3,1] [2,3,4,1]

看了看,这不是so easy嘛,直接选D。一看答案选C。

今天针对为什么选C做一个具体声明。

2、为什么调用Test1(s1),最后打印输出[1,2]
s1 := []int{1, 2}
Test1(s1)
fmt.Println(s1, s2)

我们一步一步来分析:

1. 首先将切片s1中存放的底层数组的内存地址,传入函数Test1()之后,切片s,就和切片s1指向同一个底层数组了。

2. 在Test1()函数里面进行了扩容,因为切片s1的长度为2,容量为2。所以扩容后的切片s指向新的底层数组。
3. 因切片s指向新的底层数组,所以切片s1的值没有任何改变。输出s1,仍未s1:[1,2]
3、为什么调用Test(s2),最后打印输出的[2,3,4]
func main() {
	s1 := []int{1, 2}
	s2 := s1
	s2 = append(s2, 3)
	Test1(s2)
	fmt.Println(s1, s2)
}

func Test1(s []int) {
	s = append(s, 0)
	for i := range s {
		s[i]++
	}
}

同样一步步分析:

  1. 首先当把切片s1赋值给变量s2时,实际上是把切片s1中存放的底层数组的内存地址,赋值给变量 s2。赋值完成后,变量s2变为切片类型。和切片s1指向同一个底层数组。但,在使用append函数向切片s2中追加元素3时,由于切片s2指向的底层数组,长度为2,容量为2。所以,切片s2,指向新的底层数组。
  2. 此时切片s2长度为3,容量为4。因为刚开始容量为2时,进行了扩容。切片扩容一般是扩大2倍。所以此时

切片s2的长度为3,容量为4。

  1. 在函数Test()中,使用append函数在切片s中追加了一个元素0,切片s和切片s2指向同一个底层数组,(因为在传递函数参数的时候,传递的是切片s2中底层数组的内存地址),此时在运行for-range。切片s中值变为[2,3,4,1],==是不是想着切片s2也变为该值了?==答案错了
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

slice+append陷阱 的相关文章

  • 服务计算hw7

    任务目标 设计一个 web 小应用 展示静态文件服务 js 请求支持 模板输出 表单处理 Filter 中间件设计等方面的能力 不需要数据库支持 基本要求 支持静态文件服务 支持简单 js 访问 提交表单 并输出一个表格 对 unknown
  • 同一无线络下电脑会打不开个别的网站网页,而手机却可以打开。

    今天打开一个CSDN博客链接 等了好长时间却打不开 后来还发现新浪微博也打不开 昨天还可以 今天就不行了 我的笔记本也没动什么特别的东西 然后我就分析原因 一 首先我的网友可以打开我打不开的这两个链接 相当于打不开链接的代表 说明网站是可以
  • Go_关键字、编译、转义字符

    关键字 关键字是指被go语言赋予了特殊含义的单词 共25个 关键字不能用于自定义名字 只能在特定语法结构中使用 break default func interface select case defer go map struct cha
  • Linux Debian Jenkins快速搭建配置并运行

    Jenkins安装 参考Debian Jenkins Packageshttps pkg origin jenkins io debian stable 加Key curl fsSL https pkg jenkins io debian
  • 权重实现随机抽奖

    一般抽奖是怎么实现的 在实习期间学会了一种通用的写法 在这里记录一下 最近在学Golang语法基础 这里就用Golang来写 package main import fmt time math rand func main r rand N
  • golang:环境变量GOPROXY和GO111MODULE设置

    我们安装完golang后 我们在windows的cmd命令下就可以直接查看和使用go命令和环境变量了 同样的在linux下可以在控制台使用 如下图所示 C Users lijie1 gt go env set GO111MODULE set
  • Golang连接Jenkins获取Job Build状态及相关信息

    文章目录 1 连接Jenkins 2 controller 3 module 4 router 5 效果展示 第三方包 gojenkins 方法文档 gojenkins docs 实现起来很简单 利用第三方库 连接jenkins 调用相关方
  • go 进阶 go-zero相关: 七. 拦截器与熔断拦截器

    目录 一 拦截器的基础使用 1 服务端拦截器 2 客户端拦截器 二 拦截器底层底层执行原理 三 go zero默认添加的拦截器 客户端 1 熔断器拦截器 BreakerInterceptor 服务端 一 拦截器的基础使用 在go zero
  • goland环境配置

    goland modules环境配置 下载和安装goland 环境配置 配置环境变量GOPATH 配置go modules GOPROXY代理的系统变量 工程目录中新建三个工作目录 goland中启用go modules 新建一个go程序
  • Golang 内存对齐视频

    https www bilibili com video BV1Ja4y1i7AF 简而言之 就是注意写代码的时候要把相同类型的元素放在一起 更进一步需要自己将结构体配对为32位或64位的整数倍 有助于减少额外空间消耗
  • 为什么最近听说 Go 岗位很少很难?

    大家好 我是煎鱼 其实这个话题已经躺在我的 TODO 里很久了 近来很多社区的小伙伴都私下来交流 也有在朋友圈看到朋友吐槽 Go 上海的大会没什么人 还不如 Rust 大会 比较尴尬 今天主要是看看为什么 Go 岗位看起来近来很难的样子 也
  • go-zero 开发入门-加法客服端示例

    定义 RPC 接口文件 接口文件 add proto 的内容如下 syntax proto3 package add 当 protoc gen go 版本大于 1 4 0 时需加上 go package 否则编译报错 unable to d
  • go-zero开发入门-API网关开发示例

    开发一个 API 网关 代理 https blog csdn net Aquester article details 134856271 中的 RPC 服务 网关完整源代码 file main go package main import
  • go-zero开发入门之gateway深入研究1

    创建一个 gateway 示例 main go package main import flag fmt gateway middleware github com zeromicro go zero core conf github co
  • go-zero 的 etcd 配置

    实现代码在 core discov config go 文件中 type EtcdConf struct Hosts string Key string ID int64 json optional User string json opt
  • “go mod tidy”之错误“not a valid zip file”

    执行 go mod tidy 时 遇到如下错误 rpc imports github com zeromicro go zero zrpc imports github com zeromicro go zero zrpc resolver
  • 【golang】go执行shell命令行的方法( exec.Command )

    所需包 import os exec cmd 的用法 cmd exec Command ls lah ls是命令 后面是参数 e cmd Run 多个参数的要分开传入 如 ip link show bond0 cmd
  • go开发--操作mysql数据库

    在 Go 中访问 MySQL 数据库并进行读写操作通常需要使用第三方的 MySQL 驱动 Go 中常用的 MySQL 驱动有 github com go sql driver mysql 和 github com go xorm xorm
  • golang 生成一年的周数

    GetWeekTimeCycleForGBT74082005 获取星期周期 中华人民共和国国家标准 GB T 7408 2005 参数 year 年份 GB T 7408 2005 func GetWeekTimeCycleForGBT74
  • go-carbon v2.3.4 发布,轻量级、语义化、对开发者友好的 Golang 时间处理库

    carbon 是一个轻量级 语义化 对开发者友好的 golang 时间处理库 支持链式调用 目前已被 awesome go 收录 如果您觉得不错 请给个 star 吧 github com golang module carbon gite

随机推荐

  • pandas中DataFrame的修改元素值、缺失值处理、合并操作的方法

    实验目的 熟练掌握pandas中DataFrame的修改元素值 缺失值处理 合并操作的方法 实验原理 concat合并 pd concat objs axis 0 join outer join axes None ignore index
  • Qt Quick - Dial

    Qt Quick Dial使用总结 一 概述 二 使用 一 概述 Dial 表盘类似于音响或工业设备上的传统表盘旋钮 它允许用户在一个范围内指定一个值 像CircularGauge一样 Dial可以显示刻度来指示当前值 当一个合适的步长与t
  • centos7安装apt

    centos7安装apt 搜索并下载对应版本 rpmforge release 下载地址 https www rpmfind net linux rpm2html search php query rpmforge release 执行安装
  • 大型网站在架构上应当考虑哪些问题

    大型网站在架构上应当考虑哪些问题 分层 分层是处理任何复杂系统最常见的手段之一 将系统横向切分成若干个层面 每个层面只承担单一的职责 然后通过下层为上层提供的基础设施和服务以及上层对下层的调用来形成一个完整的复杂的系统 大型网站的软件系统也
  • 【Docker】Consul构建集群服务

    1 构建Docker Cousul集群服务 1 在 后输入mkdir consul命令 然后按Enter键 创建目录Consul 示例代码如下 mkdir consul ll 效果如图1所示 2 进入consul目录 在 后面输入cd co
  • 【WIN】【C++】遍历文件夹下所有文件

    遍历某一路径下的所有文件 主要用到的两个api是 findfirst和 findnext 接口已经封装好了 直接复制getAllFiles拿去用即可 封装接口 void getAllFiles string path vector
  • 测试人员代码走查基础要点

    代码走查 是测试人员了解代码逻辑 进行测试设计的重要环节 并且有很多bug并非需要到运行程序进行测试才能发现 通过合理的代码走查方法能提前发现相当多的BUG 除常见的业务逻辑与程序逻辑不符外 本文收集了在过往工作中的经常能发现BUG的走查要
  • Cookie:使用Cookie实现记住用户的账号和密码

    目录 练习一 java web jsp 中使用cookie记住用户的账号和密码 练习二 java web jsp servert 中使用cookie记住用户的账号和密码 进阶例题 java web中使用cookie记住用户的账号和密码 练习
  • JAVA之初识springMVC框架

    1 环境 操作系统 Mac OS 10 12 6 Tomcat v7 0 JDK 1 7 工具 eclipse 2 新建项目 用eclipse新建项目 选择Dynamic Web Project 将项目字符集改为UTF 8 3 编辑web
  • SpringBoot--基础--07--多线程

    SpringBoot 基础 07 多线程 一 方式1 1 1 代码和测试 TaskConfig package fei zhou springboot4 demo2 import java util concurrent Executor
  • PAT乙级(Bascic Level)1037(C++)

    1037 在霍格沃茨找零钱 20 如果你是哈利 波特迷 你会知道魔法世界有它自己的货币系统 就如海格告诉哈利的 十七个银西可 Sickle 兑一个加隆 Galleon 二十九个纳特 Knut 兑一个西可 很容易 现在 给定哈利应付的价钱P和
  • 【ES6】Set 和 Map 数据结构

    文章目录 前言 一 Set 1 用法详解 1 1 声明方式 1 2 遍历的四种方式 2 应用场景 2 1 数组去重 2 2 合并去重 2 3交集 2 4 差集 3 WeakSet 二 Map 1 用法详解 1 1 声明方式 1 2 遍历的四
  • 论文阅读 Semantic Graph Convolutional Networks for 3D Human Pose Regression

    Semantic Graph Convolutional Networks for 3D Human Pose Regression 使用语义图卷积网络对三维人体姿态进行回归 Abstract 在这篇论文中 我们研究了学习Graph Con
  • (查看,和保存)windows下通过cmd命令符窗口查看、保存文件目录结构

    背景 有时候我们查看目录结构 或者保存目录结构信息 来对项目进行说明 一 查看文件结构 1 tree 查看tree命令操作 2 tree 只展示文件夹 tree 3 tree F 文件夹文件都展示 tree F 二 保存文件结构 在上述使用
  • PHP第三课:流程判断(下)

    上期PHP 我们学会了if判断 今天我们来学switch 看下这串代码
  • java算法题两个数组合并_算法:两个有序数组合并成一个有序数组 java语言

    题目 有两个有序数组a 和b 将它们合并成数组c 需要c 也是有序数组 思路 新建一个以两个集合长度之和为长度的新数组 从两数组最左边开始比起 把小的放入新集合 并用变量标记后一位置 每次比较都是比较的最左边未比较过的元素 通过变量 循环比
  • 用python计算灰度图像中掩模的面积(以像素为单位)

    下面是一个使用OpenCV的方法 我们用Otsu的阈值来获得一个二值图像 这个图像的前景对象是白色的 背景是黑色的 从这里我们使用cv2 countNonZero 它返回掩码上的白色像素数 找到白色像素的数量 pixels cv2 coun
  • Linux中的O_RDONLY、O_WRONLY、O_RDWR、O_APPEND、O_TRUNC、O_EXCL、O_EXCL、O_SYNC、O_NONBLOCK

    2023年7月11日 周二下午 这几个常量被定义在头文件fcntl h中 fcntl 是 file control 的缩写 它是由 file 文件 和 control 控制 两个单词组合而成的 在介绍这几个常量之前 要先介绍一下open函数
  • 【CTF】初学ROP

    在CTF PWN的题型中有一种利用方式是ROP 原理学明白了 但是实操起来一直不太理解ROP链的具体构造 为了弄明白原理 就找了一道入门题目 对照着wp进行单步调试 来理解ROP链的构造 题目 buuctf PicoCTF 2018 rop
  • slice+append陷阱

    1 前言 今天在网上看slice扩容原理 偶然看到一个slice的题目 感觉很有意思 题目如下 package main import fmt func main s1 int 1 2 s2 s1 s2 append s2 3 Test1