尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Go1.26 新特性:new(expr) 终于来了,创建指针简单了!

Go1.26 新特性:new(expr) 终于来了,创建指针简单了!
📅 发布时间:2026/6/18 11:14:11

大家好,我是煎鱼。

今天给大家分享一个 Go1.26 即将带来的实用新特性——new(expr)表达式支持。

相信写过 Go 的同学都有过这样的经历:创建一个结构体指针很简单,但要创建一个基本类型的指针就得多写好几行代码。还是挺烦人的。

这个特性能解决日常开发中的小痛点。

背景

在 Go 中,如果我们想创建一个指向结构体的指针,可以这样写:

type Person struct { name string } p := &Person{name: "alice"}

非常简洁优雅。但如果我们想创建一个指向基本类型值的指针呢?

就得这么写:

n := 42 p := &n

或者用new函数:

p := new(int) *p = 42

看起来就很不协调对吧?为什么创建复合类型的指针可以一步到位,而基本类型就得多写一个临时变量或者两行代码?

这个问题其实在社区里讨论了很久。早在 2014 年的 issue #9097[1]就有人提出过,但当时被驳回了。

为什么不能直接写 &3?

可能有同学会问:为什么不直接支持p := &3这种写法呢?

问题就出在类型系统上。在 Go 中,数字字面量3是一个无类型常量(untyped constant),它本身没有确定的类型。只有在赋值或者运算时,编译器才会根据上下文推断出具体类型。

如果允许&3这种写法,编译器就不知道该分配什么类型的内存空间 —— 是int、int64还是float64?

这会带来类型歧义,所以这条路走不通。

新提案:扩展 new 函数

Go 团队最终采纳的方案是:让new函数不仅可以接受类型参数,还可以接受表达式参数。

快速例子:

p1 := new(int, 3) p2 := new(rune, 10) p3 := new(Weekday, Tuesday) p4 := new(Name, "unspecified") ... and so on

语法规则

新的new函数行为如下:

  • 如果参数expr是一个类型为 T 的表达式,或者是一个默认类型为 T 的无类型常量表达式,那么new(expr)会分配一个类型为 T 的变量,将其初始化为expr的值,并返回其地址(类型为*T)

  • 如果参数是类型 T,那么new(T)会分配一个初始化为零值的 T 类型变量(这是原有行为)

简单来说,就是new现在既能接受类型,也能接受值了。

代码示例

基本类型指针

以前我们得这么写:

// Go 1.25 n := 42 p1 := &n fmt.Println(*p1) // 42 s := "go" p2 := &s fmt.Println(*p2) // go

现在可以直接:

// Go 1.26 p1 := new(42) fmt.Println(*p1) // 42 p2 := new("go") fmt.Println(*p2) // go
复合类型指针

对于切片这类复合类型也同样适用:

// Go 1.25 s := []int{11, 12, 13} p1 := &s fmt.Println(*p1) // [11 12 13] type Person struct{ name string } p2 := &Person{name: "alice"} fmt.Println(*p2) // {alice}

新写法:

// Go 1.26 p1 := new([]int{11, 12, 13}) fmt.Println(*p1) // [11 12 13] type Person struct{ name string } p2 := new(Person{name: "alice"}) fmt.Println(*p2) // {alice}
函数返回值指针

这个场景以前特别麻烦:

// Go 1.25 f := func() string { return "go" } v := f() p := &v fmt.Println(*p) // go

现在一行搞定:

// Go 1.26 f := func() string { return "go" } p := new(f()) fmt.Println(*p) // go

需要注意的是,传入nil仍然是不允许的:

p := new(nil) // 编译错误

实现原理

其实这个特性的实现思路很简单。当你写:

p := new(42)

编译器会将其转换为类似这样的操作:

var _tmp = 42 p := &_tmp

或者等价于:

p := new(int) *p = 42

也就是说,new(expr)本质上是为非可寻址的表达式显式分配存储空间,然后返回其地址。

这样就统一了创建指针的方式,不管是基本类型还是复合类型,都可以用类似的语法。

社区讨论中的另一个方案

其实在 proposal 讨论过程中,Rob Pike 还提出了另一个有趣的方案:让类型转换变得可寻址。

比如可以这样写:

p1 := &int(3) p2 := &rune(10) p3 := &string("hello")

这个方案的逻辑是:类型转换必然会创建新的存储空间(因为要改变类型),所以让它可寻址是合理的。

不过最终 Go 团队选择了扩展new的方案,可能是考虑到:

  1. new函数的语义本身就是"分配并初始化",扩展它更自然。

  2. 避免引入新的语法歧义。

  3. 保持&运算符语义的一致性。

实际应用场景

这个特性虽然看起来简单,但在实际开发中还是挺有用的。比如:

1. 配置选项

很多第三方库的配置结构体中会有指针类型的字段,用来区分"未设置"和"设置为零值":

type Config struct { Timeout *int MaxRetry *int } // Go 1.25 timeout := 30 config := Config{ Timeout: &timeout, MaxRetry: new(int), // 只能用 new(int) 表示 0 } // Go 1.26 config := Config{ Timeout: new(30), MaxRetry: new(0), }

2. 测试代码

在单元测试中构造测试数据时,这个特性能让代码更简洁:

testCases := []struct { input *int expected string }{ {new(42), "success"}, {new(0), "zero"}, {nil, "nil"}, }

3. 内联指针创建

在函数调用时需要传指针参数:

// Go 1.25 func process(val *string) {} s := "data" process(&s) // Go 1.26 process(new("data"))

总结

new(expr)这个特性解决了 Go 中创建基本类型指针时的不便,让代码更简洁一致。虽然改动不大,但确实提升了开发体验。

这个特性将会在 Go1.26 版本正式发布,由 Alan Donovan、Ian Lance Taylor、Rob Pike 等核心团队成员推动完成。

对于我们 Go 开发者来说,以后写代码可以少定义临时变量了,代码也会相对干净些。

花了 11 年啊。绝了,真的服了。

参考资料

[1]

#9097:https://github.com/golang/go/issues/9097

关注和加煎鱼微信,

一手消息和知识,拉你进技术交流群👇

你好,我是煎鱼,出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉,点击蓝字查看我的出书之路。

日常分享高质量文章,输出 Go 面试、工作经验、架构设计,加微信拉读者交流群,和大家交流!

原创不易 点赞支持

相关新闻

  • 喝茶减重效率翻倍!SAT-3D助你精准管理饮食!
  • 实验室环境下Multisim主数据库权限问题全面讲解
  • LangFlow行测题目解析生成辅助工具

最新新闻

  • 深入理解Linux终端控制:tcgetattr与termios结构体实战指南
  • Ultralytics RegionCounter工业级计数落地实践
  • Windows系统优化终极指南:三分钟让你的电脑快如新机!
  • 2022 AI工程化落地实操指南:从大模型到可控生成与指令微调
  • MPC857T勘误文档解析:嵌入式开发中规避硬件设计陷阱的关键
  • 团队冲刺7

日新闻

  • 2026年不锈钢卷板厂家推荐排行榜:冷轧热轧/304/201不锈钢卷板,高颜值耐腐蚀源头厂家实力精选 - 企业推荐官【官方】
  • FLUX.1-dev FP8模型实战指南:24GB以下显卡高效部署方案
  • 2026佛山长途搬家价目表:跨省跨市搬家费用完整计算指南 - 从来都是英雄出少年

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号