golang 什么时候应该用 slices 或者 slices 的指针

Everything in Go, ever, always, is passed by value

与 C 语言家族的所有语言一样,Go 语言中的所有内容都是通过值传递的。也就是说,函数总是获得被传递内容的副本,就像有一条赋值语句将值赋给参数一样。例如,向函数传递一个 int 值会得到 int 的副本,传递一个指针值会得到指针的副本,但不会得到指针指向的数据。(关于这对方法接收器的影响,请参阅后面章节的讨论)。

映射和切片值的行为类似指针:它们是描述符,包含指向底层映射或切片数据的指针。复制映射或切片值并不会复制其指向的数据。复制接口值则是复制接口值中存储的内容。如果接口值包含一个结构体,复制接口值就会复制该结构体。如果接口值保存的是指针,复制接口值就会复制指针,但不会复制指针指向的数据。

参考代码测试结果: colobu.com/2016/10/28/...

Slices vs pointers to slices (如何选择)

从逻辑上讲,Slices 是一个由三个字段组成的结构体:

  • 一个指向片段后备数组的指针(该数组实际包含片段的元素)和两个 ints:
  • Slices 的容量
  • Slices 的长度

在传递和分配 Slices 值时,这些结构值会被复制:一个指针和两个整数。 正如你所看到的,当你传递一个 Slices 值时,后备数组不会被复制,只有一个指向它的指针。

也就是说,在 Slices 值传值过程的设计上,本身就是很轻量的,只复制了一个指针(的值),并没有复制全部数据。

现在,让我们考虑一下什么时候需要使用普通 Slices 或指向 Slices 的指针。

如果您担心性能(复制内存所需的内存分配和/或CPU周期),那么这些担忧是没有根据的: 在传递切片时复制三个整数在当今的硬件上非常便宜。使用指向 slice 的指针会使复制速度加快一点点------复制单个整数而不是三个整数------但是这些节省很容易被两个事实所抵消:

  • 几乎可以肯定,slice 的值最终会在堆上分配,这样编译器就可以确保它的值在跨越函数调用边界时仍然存在------这样您将为使用内存管理器付费,而垃圾收集器将承担更多的工作。

  • Using a level of indirection reduces data locality: 访问RAM的速度很慢,所以cpu有缓存,可以在读取数据的地址后面预取数据。如果控制流立即在另一个位置读取内存,那么预取的数据将被丢弃:缓存垃圾。

那么有没有一种情况下你想要一个指向切片的指针?是的。例如, built-in append 函数被定义为:

go 复制代码
func append(*[]T, T...)

而不是

scss 复制代码
func append([]T, T...) []T

(注意:这里的"T"实际上意味着"任何类型",因为"append"不是一个库函数,不能在普通 Go 中合理地定义;这是一种伪代码。)

也就是说,它可以接受指向切片的指针,并可能 替换 指针指向的切片,因此您可以将其定义为为 append(&slice, element) 而不是 slice = append(slice, element)

当你需要直接操作增删一个 slice ,并且用操作后的 slice,替换原来的 slice,这个时候可以像 append 一样,最好是使用指针。

其他的情况,不用指针。

但老实说,在我处理过的真实Go项目中,我记得使用指针指向片的唯一情况是为了池化大量重用的片,以节省内存重新分配。那个唯一的例子只是因为 sync.Pool keeping elements of type interface{} 这在使用指针时可能更有效。

Slices of values vs slices of pointers to values (关于这个话题其实和上面没有区别)

参考: stackoverflow.com/questions/7...

相关推荐
刘大辉在路上3 小时前
突发!!!GitLab停止为中国大陆、港澳地区提供服务,60天内需迁移账号否则将被删除
git·后端·gitlab·版本管理·源代码管理
追逐时光者4 小时前
免费、简单、直观的数据库设计工具和 SQL 生成器
后端·mysql
初晴~5 小时前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
盖世英雄酱581365 小时前
InnoDB 的页分裂和页合并
数据库·后端
小_太_阳5 小时前
Scala_【2】变量和数据类型
开发语言·后端·scala·intellij-idea
直裾5 小时前
scala借阅图书保存记录(三)
开发语言·后端·scala
星就前端叭6 小时前
【开源】一款基于Vue3 + WebRTC + Node + SRS + FFmpeg搭建的直播间项目
前端·后端·开源·webrtc
小林coding7 小时前
阿里云 Java 后端一面,什么难度?
java·后端·mysql·spring·阿里云
AI理性派思考者7 小时前
【保姆教程】手把手教你在Linux系统搭建早期alpha项目cysic的验证者&证明者
后端·github·gpu