当前位置: 首页 > news >正文

Go 数组和切片反思

切片的底层数据结构是数组,所以,切片是基于数组的上层封装,使用数组的场景,也完全可以使用切片。

类型比较

我看到 go 1.17 有对切片和数组转换的优化,禁不住纳闷,有什么场景是必须数组来完成的呢?我特意去查了一下数组和切片的核心差异,刨去有的没的,核心就 2 点:

  • 数组是可比较的,切片是不可比较的,验证的方式也非常简单。声明一个 map 类型,如果 key 的类型是切片,会报如下的编译错误。如果是数组类型,可以正常编译。
  • 数组赋值是值拷贝,切片赋值是引用拷贝,切片类型在值拷贝前后,底层共用的还是同一个数组,而数组的值拷贝就是值拷贝。

在这里插入图片描述
在查看的过程中,我也有发现数组指针的用法,除了可以通过数组本身来操作数组,还可以通过数组指针来操作。而这种使用手法,是切片不具备的。

下面的代码,通过数组指针 (&b) 可以像直接使用 b 一样访问数组的元素,而通过使用指针赋值的方式,也可以让两个变量共用同一个数组。

func main() {var b = [3]int{11, 12, 13} //fmt.Println((&b)[0])fmt.Println(b[0])
}

下面数组的赋值过程, a 和 b 是值拷贝,完全独立的两份数据,b 数组修改第一个元素,并不会影响到数组 a。而 c 和 a 是数组指针类型的值拷贝,共享同一份数组数据,c 数组修改第一个元素,也就修改了 a 指向的数组。

func main() {var a = [3]int{11, 12, 13} //b := ab[0] = 10fmt.Println(a[0])fmt.Println(b[0])c := &ac[0] = 10fmt.Println(a[0])fmt.Println(c[0])
}

类型转换

数组和切片的转换,说实话,在业务开发的过程中,我基本上没有用到这种转换场景。因为切片的底层是数组,数组可以直接转换为切片类型,转换后,切片和数组共享同一份空间。

func main() {var a = [3]int{11, 12, 13} b := a[:len(a)]fmt.Printf("%T,%T", b, a)
}

仔细想想,切片在 go 中的结构为 SliceHeader ,除了数组 Data 部分,还包含了 Len 和 Cap 两个属性。所以,go 数组转切片的过程,也是封装这个 SliceHeader 的过程。

type SliceHeader struct {Data uintptrLen  intCap  int
}

但在 1.17 之前,切片是不能直接转换为数组的,要想转换为数组,就需要通过 unsafe 包来实现。不过,切片要转换为数组,相比,数组转换为切片,要简单很多。

原理上就是获取切片底层数组的第一个元素的指针,转换为数组的指针。

func main() {var a = []int{11, 12, 13} //b := (*[3]int)(unsafe.Pointer(&a[0]))fmt.Println(b)
}

现在 go 1.17 默认也支持了这个转换,转换的方式也很好理解,转换为数组类型的指针。因为是指针,所以,转换后的数组 b 和 a 仍然还是共用同一份数据。

为什么默认转换使用的类型是数组指针 (*[3]int),而非 ([3]int) 呢?我理解,如果是值类型的话,还需要底层数据的拷贝,语义上也没有指针类型好理解。

func main() {var a = []int{11, 12, 13} //b := (*[3]int)(a)fmt.Println(b)
}

应用

结合以往的工作,比较适合使用数组替代切片的场景大概就是:控制并发的顺序。

我们有一组数组 reqs,要请求某一个接口。然后,需要按照请求的顺序,返回请求的结果。我们使用 go 协程并发请求接口,然后基于请求的索引,将接口返回的结果存储到对应索引数组的位置。

因为数组的个数是固定的,所以,这种场景还是比较少的


func main() {var reqs [3]interface{} = [...]interface{}{1, 2, 3}var res [3]interface{}for i:= range reqs {go func(index int) {res[index] = reqs[index]}(i)}time.Sleep(time.Second)fmt.Println(res)
}

相关文章:

Go 数组和切片反思

切片的底层数据结构是数组,所以,切片是基于数组的上层封装,使用数组的场景,也完全可以使用切片。 类型比较 我看到 go 1.17 有对切片和数组转换的优化,禁不住纳闷,有什么场景是必须数组来完成的呢&#x…...

win10电脑性能优化设置

win10电脑性能优化设置 目录win10电脑性能优化设置1.桌面图标显示2.wini2.1 “系统”2.1.1专注助手 关2.1.2 电源和睡眠 设置为从不2.1.3 存储 开2.2 网络和Internet2.3 个性化2.4 应用2.5 账户2.6 游戏2.7 隐私墨迹书写和键入个性化:关活动历史记录:全部…...

作为初学者必须要了解的几种常用数据库!

现在已经存在了很多优秀的商业数据库,如甲骨文(Oracle)公司的 Oracle 数据库、IBM 公司的 DB2 数据库、微软公司的 SQL Server 数据库和 Access 数据库。同时,还有很多优秀的开源数据库,如 MySQL 数据库,Po…...

小红书日常实习一面面经

时间:2月13下午 平台:赛码网,视频面大概70分钟顺序大致是下面,讲到哪问到哪,基础知识最好要结合项目或者实际回答,没录音不完全,有错误请指正首先面试官人超级好,细心提问,耐心解答问…...

将Nginx 核心知识点扒了个底朝天(一)

什么是Nginx? Nginx是一个 轻量级/高性能的反向代理Web服务器,用于 HTTP、HTTPS、SMTP、POP3 和 IMAP 协议。他实现非常高效的反向代理、负载平衡,他可以处理2-3万并发连接数,官方监测能支持5万并发,现在中国使用ngin…...

SSM项目搭建保姆级教程

文章目录1、什么是SSM框架1.1、持久层1.2、业务层1.3、表现层1.4、View层1.5、SpringMVC执行流程1.6、MyBatis2、SSM实战搭建2.1、创建工程2.2、添加依赖2.3、配置spring.xml文件2.4、配置web.xml文件2.5、log4j.properties2.6、准备表2.7、实体类2.8、mapper2.9、service2.10、…...

LeetCode 350. 两个数组的交集 II

原题链接 难度:easy\color{Green}{easy}easy 题目描述 给你两个整数数组 nums1nums1nums1 和 nums2nums2nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现…...

Python可以解码吗,解码打码是如何实现的

前言 咳咳,进来的铁汁都是抱着学习的心态进来看的吧,咱今天不讲解解码,咱来说说python如何来实现打码功能~ 这一个个进来的 都是标题党吧哈哈哈 有兴趣的可以继续看看哦 最近重温了一档综艺节目 至于叫什么 这里就不细说了 老是看着看着就…...

Jackson 序列化:Cannot deserialize value of type `java.time.LocalDateTime`

问题描述 使用 jackson 反序列化异常如下: Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.time.LocalDateTime from String “2023-02-13 19:43:01”: Failed to deserialize java.time.LocalDat…...

机试_3_数据结构(一)_习题

数据结构(一)——练习题 学习完第三章-数据结构(一)之后,当然要做相应地练习啦~ 注:上述习题都可以在牛客进行测试。 例如,第2题链接:计算表达式_牛客题霸_牛客网 (nowcoder.com)…...

《Hadoop篇》------HDFS与MapReduce

目录 一、HDFS角色职责总结 二、CheckPoint机制 三、Mapreduce序列化 四、Mapper 4.1、官方介绍 4.2、Split计算 4.3、Split和block对应关系 4.4、启发式算法 五、MapTask整体的流程 六、压缩算法 6.1、压缩算法适用场景 6.2、压缩算法选择 6.2.1、Gzip压缩 6.2…...

网络爬虫简介

前言 没什么可以讲的所以就介绍爬虫吧 介绍 网络爬虫(英语:web crawler),也叫网路蜘蛛(spider),是一种用来自动浏览万维网的网络机器人。其目的一般为编纂网络索引。 网路搜索引擎等站点通过…...

通过4个月的自动化学习,现在我也拿到了25K的offer

毕业后的5年,是拉开职场差距的关键时期。有人通过这5年的努力,实现了大厂高薪,有人在这5年里得到贵人的赏识,实现了职级的快速拔升,还有人在这5年里逐渐掉队,成了职场里隐身一族,归于静默。 而…...

分库分表了解

数据切分根据其切分类型,可以分为两种方式:垂直(纵向)切分和水平(横向)切分一:垂直(纵向)切分【基于表或字段划分,表结构不同】1:垂直分库根据业务…...

docker中 gitlab 安装、配置和初始化

小笔记:gitlab配置文件 /etc/gitlab/gitlab.rb 配置项jcLee95 的CSDN博客:https://blog.csdn.net/qq_28550263?spm1001.2101.3001.5343 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/1…...

有哪些好用的C++Json库?

文章目录RapidJSONJSON for Modern CBoost.PropertyTreeJanssonPicoJSONC REST SDKnlohmann json(ky用的这个)jsoncpp(cw用的这个)RapidJSON RapidJSON是一个快速、高效的C JSON解析器和生成器,支持SAX和DOM两种解析模…...

Docker 快速上手学习入门教程

目录 1、docker 的基础概念 2、怎样打包和运行一个应用程序? 3、如何对 docker 中的应用程序进行修改? 4、如何对创建的镜像进行共享? 5、如何使用 volumes 名称对容器中的数据进行存储?// 数据挂载 6、另一种挂载方式&…...

深度学习笔记:误差反向传播(1)

1 计算图 计算图使用图(由节点和边构成的图)来表达算式。 如图,我们用节点代表运算符号,用边代表传入的参数,即可算出购买苹果和橘子的总价格。 2 计算图的局部计算 局部计算意味着每个节点只处理和其相关的运算&…...

锁相环(1)

PLL代表相位锁定环。顾名思义,如下图所示,PLL是一种具有反馈循环的电路,可将反馈信号的相/频率保持与参考输入信号的相/频率相同(锁定)。 如下图所示,如果参考输入和反馈输入之间存在相位差,则…...

2023金三银四跳槽必会Java核心知识点笔记整理

现在互联网大环境不好,互联网公司纷纷裁员并缩减 HC,更多程序员去竞争更少的就业岗位,整的 IT 行业越来越卷。身为 Java 程序员的我们就更不用说了,上班 8 小时需要做好本职工作,下班后还要不断提升技能、技术栈&#…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...