Go 1.26 内置函数 new 新特性

news/2025/9/26 12:05:18/文章来源:https://www.cnblogs.com/apocelipes/p/19113233

目前golang 1.26的各种新特性还在开发中,不过其中一个在开发完成之前就已经被官方拿到台面上进行宣传了——内置函数new功能扩展。

每个新特性其实都有它的背景故事,没有需求的驱动也就不会有新特性的诞生。所以在介绍这个新特性之前我们先来了解下是什么样的场景催生了这个功能。

如果你经常浏览一些大型的go项目,尤其是那些需要频繁和JSON、GRPC或者yaml打交道的项目,比如k8s,你会发现这些代码库会提供一些和下面代码类似的帮助函数:

func getPointerValue[T any](v T) *T {return &v
}

这个是我用泛型改写的,代码库里通常都是getIntPointerValue(int) *int这样非泛型函数。函数的作用很简单,返回指向自己参数的指针。但这样简单的三行代码有什么用呢?

用处有好几个,第一个是在json或者rpc里有时候我们会用指针的nil来表示这个值没有生效,和字段类型的零值做区分,但这使得给字段赋值变麻烦了:

type Data struct {Num *uint
}d := &Data{}
d.Num = &12345 // 编译错误
d.Num = getPointerValue(12345)

这行代码d.Num = &12345是语法错误,因为在golang里规定不能对字面量以及常量取地址。不仅如此,类似d.Num = &getNum()这样的代码也是无法编译的,因为go也规定了不能对右值取地址。

如果没有帮助函数,我们需要用一个中间变量接住这些值,然后再把这个中间变量的指针赋值给结构体的字段。

第二个作用在于防止潜在的内存泄漏:

type BigStruct struct {// 100个其他字段Num int
}bigObj := &BigStruct{....}
bigSlice := make([]int, 1024)d1.Num = &bigObj.Num
d2.Num = &bigSlice[1000]

猜猜如果d1d2需要很长时间才能被释放会发生什么。答案是bigObjbigSlice也会一直存在不被释放,因为golang中结构体、数组/切片只要还有指针指向自己的字段或者元素,那么整个结构体和数组/切片的内存都不能被释放。换句话说因为你的Data结构体持有了一个8字节的指针,会导致它背后十几KB的内存一直没法释放,尽管这些内存中的99%你完全用不到。这在比较宽泛的定义上已经属于是内存泄漏了。

所以这时候帮助函数就起作用了。getPointerValue的参数不是指针,因此会把传进来的值拷贝一份,然后再取拷贝出来的新变量的指针,这样就不会有指针指向那些大对象的字段或者元素了,这些大对象也可以尽快得到释放从而不会浪费内存。

背景故事到此结束,到这里其实你也能猜出new被扩展的新功能大致是什么了。

new在1.26中获得的新功能是可以接受一个表达式,它会复制表达式的结果到同类型的变量里并返回指向这个变量的指针。

看个例子:

new(1234) // *int, 指向的值是1234func getString() string {return "apocelipes"
}
new(getString()) // *string, 指向的值是"apocelipes"s := "Hello, "
new(s + getString() + "!") // *string, 指向的值是表达式的结果"Hello, apocelipes!"

功能很简单,相当于把上面的帮助函数getPointerValue集成到了现有的内置函数new里。这能让我们简化一些代码。

不过按照go团队以往的做法,如果只是简化代码的话其实是不会在原有的内置函数上新增功能的。现在这么做了说明还有额外的好处——性能。

我们看个性能测试:

func BenchmarkOld(b *testing.B) {for b.Loop() {p := getPointerValue(123)if p == nil || *p != 123 {b.Fatal()}}
}func BenchmarkNew(b *testing.B) {for b.Loop() {p := new(123)if p == nil || *p != 123 {b.Fatal()}}
}

这段代码需要master分支上的go编译器才能正常编译运行,我使用的版本是go1.26-devel_d7a38adf4c

结果:

image

可以看到使用帮助函数要额外多分配一次内存,速度也更慢。这是因为golang的逃逸分析主要保证内存安全,而在优化上比较保守,所以在处理我们的帮助函数时哪怕这个函数已经被内联,编译器还是会选择分配一块堆内存再返回指向这块内存的指针。换句话说,编译器不够“聪明”。

但内置函数就不一样了,内置函数是被编译器特殊处理的,new会被编译器改写:

p1 := new(int)
// 改写成
// var tmp int
// p1 := &tmpp2 := new(12345)
// 改写成
// var tmp int
// tmp = copy 12345
// p2 := &tmp

可以看到new是先在当前作用域里创建一个临时变量,然后再把表达式的结果复制进去的。全程没有其他的函数调用。

对于改写后的代码,逃逸分析有充足的信息来决定改写产生的tmp应该分配在栈上还是堆上,比起帮助函数来说获得了更多的优化机会,因此性能也更好。

所以官方才有底气提前宣传,毕竟不仅解决了痛点,还有额外的收获。

总结

1.26开始内置函数new的参数除了能接受一个类型名称,现在还可以接收任意的表达式了。

在新版本中我们可以直接利用内置函数new不需要写帮助函数了,同时还能收获更高的性能。

当然,1.26的新特性开发窗口还没结束,不能保证最终发布的功能和文章里介绍的一模一样,但看官方这架势这个新特性大概率是板上钉钉了,先用这篇文章尝个鲜也未尝不可。

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

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

相关文章

基于SpringBoot及PostgreSQL的国家减肥食谱管理项目(上):区域与省份安装搭建

基于SpringBoot及PostgreSQL的国家减肥食谱管理项目(上):区域与省份安装搭建pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-f…

基于BP神经网络的激光焊接数据预测

基于BP神经网络的激光焊接数据预测的系统化方法,结合核心原理、实现步骤及工程优化策略,适用于焊接质量控制和工艺参数优化: 一、BP神经网络原理与激光焊接预测适配性核心机制 BP神经网络通过误差反向传播调整权重,…

重要公式 - Emi

重要的三角函数公式 \[sin\alpha cos\beta=\frac{sin(\alpha+\beta)+sin(\alpha-\beta)}{2} \]\[cos\alpha cos\beta=\frac{cos(\alpha+\beta)+cos(\alpha-\beta)}{2} \]\[sin\alpha sin\beta=-\frac{cos(\alpha+\beta…

Pandawiki:企业知识管理的全能管家

Pandawiki:企业知识管理的全能管家在当今这个信息爆炸的时代,每个企业都面临着一个共同的挑战:如何有效地管理和利用内部积累的海量知识资产?从产品文档到技术规范,从客户问答到项目经验,这些宝贵的信息往往散落…

珠宝网站建设做网站项目流程图模板

Spring的开发要点总结 文章目录 【JavaEE】Spring的开发要点总结(1)1. DI 和 DL1.1 DI 依赖注入1.2 DL 依赖查询1.3 DI 与 DL的区别1.4 IoC 与 DI/DL 的区别 2. Spring项目的创建2.1 创建Maven项目2.2 设置国内源2.2.1 勾选2.2.2 删除本地jar包2.2.3 re…

apt 还是 uv

一句话结论装系统级软件(C/CUDA、驱动、编译链) → 用 apt 纯 Python 项目/虚拟环境/依赖锁文件 → 用 uv;它比 apt 里的 python3-xxx 新、快、隔离,但不能装非 Python 组件下面给你展开对比,按“能干什么、不能干…

软件构造中的数据处理(sql) 6章

JDBC编程步骤 1.加载数据库驱动 2.建立数据库连接 3.创建Statement/PreparedStatement 4.执行SQL语句 5.处理查询结果(ResultSet) 6.关闭资源(Connection/Statement/ResultSet)

鹿鼎记豪侠传:Rust 重塑 iOS 江湖(下) - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

US$39 CAS Mileage Reset Authorization for CGDI Prog BMW MSV80 CAS1 CAS2 CAS3 CAS3+ via OBD

CAS Mileage Reset Authorization for CGDI Prog BMW MSV80 CAS1 CAS2 CAS3 CAS3+ via OBDWith this authorization, you can change mileage on BMW CAS1 CAS2 CAS3 CAS3+ CAS3++ via OBD.No need shipping. Please p…

是普通网站地图好还是rss地图好一点九江 网站建设

为增强安全性,平台可安装ssl证书。对于平台不同的组成部分需要采用不同的方式,使用不同的证书格式: 一、前端 前端采用nginx部署,安装证书步骤如下(linux window版一样): 1、conf目录下增加cert…

树的重心(邻接表)

输入样例:9 1 2 1 7 1 4 2 8 2 5 4 3 3 9 4 6期望输出:4代码实现:#include<bits/stdc++.h> using namespace std;const int N =1e5+10 , M=2*N;int n,m; int h[N],e[M],ne[M],idx; bool vis[N]; int ans=N ;v…

语音芯片怎样接? 语音芯片有哪些常见接口类型?

目录: 语音芯片怎样接? 语音芯片有哪些常见接口类型? UART接口如何实现数据传输? UART与I2C接口有何不同? UART通讯的常见故障有哪些? UART通信中时钟同步的原理: 语音芯片怎样接? 语音芯片的连接方式取决于其…

详细介绍:2025华为杯A题B题C题D题E题F题选题建议思路数学建模研研究生数学建模思路代码文章成品

详细介绍:2025华为杯A题B题C题D题E题F题选题建议思路数学建模研研究生数学建模思路代码文章成品pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !i…

上饶市住房和城乡建设局网站电商培训视频教程

一、分类任务 构建分类网络模型 必须继承nn.Module且在其构造函数中需调用nn.Module的构造函数无需写反向传播函数&#xff0c;nn.Module能够利用autograd自动实现反向传播Module中的可学习参数可以通过named_parameters()返回迭代器 from torch import nn import torch.nn.f…

Gitee vs. GitLab:中国开发者为何选择本土代码托管平台?

Gitee vs. GitLab:中国开发者为何选择本土代码托管平台? 在数字化转型和信创产业蓬勃发展的背景下,中国开发者正面临一个关键选择:是继续依赖国际化的GitLab,还是拥抱本土化的Gitee?作为国内最大的代码托管平台,…

AtCoder Beginner Contest 424

Atcoder 424 A-F题解A - Isosceles 核心代码: signed main() {ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);int a, b, c;cin >> a >> b >> c;if(a == b || b == c || a == c) cout << …

US$39 BAV-Key Adapter for Yanhua Mini ACDP

BAV-Key Adapter for Yanhua Mini ACDPBAV-Key Adapter will be needed for Module 1 BMW CAS1-CAS4+, Modul 9 Land Rover and Module10 for Porsche.Package List:1pc x BAV-Key Adapter for Yanhua Mini ACDP Pictu…

可以放钓鱼网站的免费空间做一个网站以及app多少钱

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 孤立词识别是语音识别领域的一个重要分支&#xff0c;其目标是将输入的语音信号转换为计算机可…

ClkLog埋点分析系统-私有化部署+轻量灵活

ClkLog 自发布以来已有两年时间。从最初的社区版,到如今不断迭代出专业版与企业版,我们一直紧跟用户需求,不断优化产品,只为做出真正“小而美、好上手、落地快”的用户行为分析系统。在ClkLog 2.0 版本发布之际,我…

级数 - Emi

几何级数定义:每一项乘以一个固定的数得到下一项(不就是等比级数?) 求和: $$S_n=\frac{a(1-r^n)}{1-r}$$ 这里\(S_n\)是前\(n\)项的和, \(a\) 是第一项, r 是公比. 然后呢,整个级数的和就是前\(n\)项和取\(n\)趋近…