一个新细节,Go 1.17 将允许切片转换为数组指针!

在 Go 语言中,一个切片(slice)包含了对其支持数组的引用,无论这个数组是作为一个独立的变量存在于某个地方,还是仅仅是一个为支持分片而分配的匿名数组。

其切片基本结构都如下:

// runtime/slice.go
type slice struct {
	array unsafe.Pointer // 指向底层数组的指针
	len   int // 长度 
	cap   int // 容量
}

目前切片这种支持数组的方式可能会导致切片出现有趣的内存泄漏或对你的切片产生令人惊讶的变化。
另外很重要的一点,在 Go 1.16 及以前,不存在将从切片类型转换为数组类型的安全方法,比较无奈。
我们只能通过调用标准库 reflect 或 unsafe,通过编写不安全的代码来做到这一点:

(*[10]byte)(unsafe.Pointer(&b[0]))

显然这是不优雅的,官方自己都不推荐使用 unsafe,一旦处理出错了,可能还会导致致命错误,比较不可控。

其实早在2009 年,就有人提出相关疑惑,希望解决这个问题:

在这里插入图片描述
终于,在 Go 1.17 中,这将成为可能,因为从 commit-id #1c268431f4 开始的一系列变化,更新了规范:
在这里插入图片描述
规范中对此的描述很直接:

Converting a slice to an array pointer yields a pointer to the underlying array of the slice. If the length of the slice is less than the length of the array, a run-time panic occurs.

如果切片的长度比数组的长度长是无害,能够正常运行。
如果比数组长的切片,意味着你的数组将不能访问原始切片的所有支持数组。
另外规范中提供了一些新的例子,在 Go1.17 中我们可以这么用:

s := make([]byte, 2, 4)
s0 := (*[0]byte)(s)      // s0 != nil
s2 := (*[2]byte)(s)      // &s2[0] == &s[0]
s4 := (*[4]byte)(s)      // panics: len([4]byte) > len(s)

var t []string
t0 := (*[0]string)(t)    // t0 == nil
t1 := (*[1]string)(t)    // panics: len([1]string) > len(s)

  • 变量 s2 的转换:其将切片底层的数组转换了出来,这种转换不会(也不能)分配一个新的数组,从而保证了它的效率。
  • 变量 s0 和 t0 的转换:其将一个非空的片断转换为一个 0 长度的数组。虽然长度为 0 的数组,你不能用它做任何事情,但依然必须给一个有效的指针,也就是 nil。

需要注意,现在还没有办法像类型断言那样,检查他是否会因为越界等原因出现 panic 事件。如果你认为你可能有一个太短的片断,可能会导致 panic 事件,那么你需要使用 if 来进行预判断。
同时标准库 reflect 也会进行更新,以便于支持从切片到数组指针的转换,如果你正在用 reflect 做相关转换工作,建议阅读该提交中的注意事项。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Sentinel流量防卫兵

1、分布式服务遇到的问题 服务可用性问题 服务可用性场景 服务雪崩效应 因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程,就叫服务雪崩效应导致服务不可用的原因: 在服务提供者不可用的时候,会出现大量重试的情况&…

鸿蒙内核源码分析(原子操作篇) | 谁在为原子操作保驾护航

基本概念 在支持多任务的操作系统中,修改一块内存区域的数据需要“读取-修改-写入”三个步骤。然而同一内存区域的数据可能同时被多个任务访问,如果在修改数据的过程中被其他任务打断,就会造成该操作的执行结果无法预知。 使用开关中断的方…

CTF(Web)中关于执行读取文件命令的相关知识与绕过技巧

在我遇到的题目中,想要读取文件必然是要执行cat /flag这个命令,但是题目当然不会这么轻松。让你直接cat出来,必然会有各种各样的滤过条件,你要做的就是尝试各种方法在cat /flag的基础上进行各种操作构建出最终的payload。 下面我…

38-1 防火墙了解

一、防火墙的概念: 防火墙(Firewall),也称防护墙,是由Check Point创立者Gil Shwed于1993年发明并引入国际互联网(US5606668 [A]1993-12-15)。它是一种位于内部网络与外部网络之间的网络安全系统,是一项信息安全的防护系统,依照特定的规则,允许或是限制传输的数据通过。…

《QT实用小工具·五十八》模仿VSCode的可任意拖拽的Tab标签组

1、概述 源码放在文章末尾 该项目实现了模仿VSCode的可任意拖拽的Tab标签组,包含如下功能: 拖拽标签页至新窗口 拖拽标签页合并控件 无限嵌套的横纵分割布局(类似Qt Creator的编辑框) 获取当前使用的标签组、标签页 自动向上合并…

【CTF Reverse】XCTF GFSJ0490 simple-unpack Writeup(UPX壳+脱壳+反汇编)

simple-unpack 菜鸡拿到了一个被加壳的二进制文件 解法 拉进 exeinfope。 检测到是 UPX 打包的 ELF 文件。 NOT Win EXE - .o - ELF [ 64bit obj. Exe file - CPU : AMD x86-64 - OS/ABI: Linux/GNU ]Detected UPX! packer - http://upx.github.io -> try unpack with &…

Linux第三节--常见的指令介绍集合(持续更新中)

点赞关注不迷路!,本节涉及初识Linux第三节,主要为常见的几条指令介绍。 如果文章对你有帮助的话 欢迎 评论💬 点赞👍🏻 收藏 ✨ 加关注👀 期待与你共同进步! Linux下基本指令 1. man指令 Linu…

在uniapp里面使用 mp-html 并且开启 latex 功能

在uniapp里面使用 mp-html 并且开启 latex 功能 默认情况下 mp-html 是不会开启 latex 功能的, 如果需要开启 latex 功能是需要到代码操作拉取代码自行打包的。 这里说一下 mp-html 里面的 latex 功能是由 https://github.com/rojer95/katex-mini 提供的技术实现,…

科技园3d数据可视化展示

我们的园区安防3D可视化报警平台通过高精度三维建模技术,将管理对象场景以立体、直观的方式呈现,实现管理对象的全面可视化。同时,平台与各类业务系统深度对接,实现数据、告警、远程操作的整合展示和联动响应,构建中心…

Java基础教程 - 4 流程控制

更好的阅读体验:点这里 ( www.doubibiji.com ) 更好的阅读体验:点这里 ( www.doubibiji.com ) 更好的阅读体验:点这里 ( www.doubibiji.com ) 4 流程控制 4.1 分支结构…

CSS Web服务器、2D、动画和3D转换

Web服务器 我们自己写的网站只能自己访问浏览,但是如果想让其他人也浏览,可以将它放到服务器上。 什么是Web服务器 服务器(我们也会称之为主机)是提供计算服务的设备,它也是一台计算机。在网络环境下,根据服务器提供的服务类型不…

C++构造函数和析构函数的调用顺序

一般情况下,调用析构函数的次序正好与调用构造函数的次序相反,也就是最先被调用的构造函数,其对应的析构函数最后被调用,而最后被调用的构造函数,其对应的析构函数最先被调用。 当然对象的构造函数和析构函数调用时机和…

DRF的序列化【2】

【0】前提概要 【1】基于 View JsonResponse 编写的 5 个接口: 序列化自定义处理: 你需要自己编写序列化逻辑。处理 JSON 格式的 POST 请求数据: 从 request.body 中获取数据,并使用 json.loads() 解析成字典,然后创建相应的对象。request.…

JS基础:变量的详解

你好,我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 云桃桃,大专生,一枚程序媛,感谢关注。回复 “前端基础题”,可免费获得前端基础 100 题汇总,回复 “前端基础路线”,可获取…

基于51单片机NEC协议红外遥控发送接收proteus仿真设计

1.主要功能: 设计一个51单片机红外遥控发射接收proteus仿真设计 功能要求: 1、使用单片机模拟红外遥控器发射红外编码; 2、利用从机接收红外编码,并将编码以16进制显示到数码管上。 需注意仿真中51单片机芯片是兼容的&#x…

Web网页项目实战-----小兔鲜儿项目

本网站是一个电商网站,主要由Html、CSS、JS来完成,实现的功能主要是可以购买产品,展示产品,查看订单等功能,效果如下,如有需要项目代码的可以私信我,或者文章底下评论,我给分享原项目…

爬虫学习(2)破解百度翻译

代码 import requests import jsonif __name__ "__main__":url https://fanyi.baidu.com/sug#post请求参数处理(同get请求一致)headers {"User-Agent": Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …

【C语言】第一个C程序:hello world

printf简介 printf是C语言提供的库函数,可以在屏幕上打印格式化数据。这里不作展开,只需要知道,如果要打印hello world,就把双引号引起来的"hello world"作为参数传给printf就行了。如果想要在打印后换行,要…

【Linux】冯·诺依曼体系结构

要想谈进程,我们就不能只谈进程,我们如果想搞清楚什么是进程,就要从操作系统讲起。我们现在的不管是Linux或是Windows或是安卓等操作系统,它们都有一个相同点,那就是遵循冯诺依曼体系结构,我们看一下冯诺依…

如何让你的排单更快?

一般我们都喜欢做打板借用快速通道!但是目前快速通道也是共享通道,独立单元格基本不开发。 想要排单更快,想要隔夜打板,我们到底应该怎么做呢? 想要排单更快,说白了就是要提高你的交易速度!一&a…