分享
大家好,我是 polarisxu。
在 Go 语言中,我们经常会遇到需要"创建一个基本类型的指针"的场景。然而,相比结构体可以通过 `&Person{}` 轻松获取指针,基本类型(如 `int`, `string`)的取地址操作一直显得有些"笨拙"。
Go1.26 将改变这一局面,引入了一个备受关注的提案 **`new(expr)`** 。这个改动虽然看起来很小,但却解决了 Go 社区长久以来的一个痛点。
------
## **1. 痛点:尴尬的取地址操作**
在目前的 Go 版本(1.25 及以下)中,如果你想创建一个指向整数 `42` 的指针,你不能直接写 `&42`(编译报错),你通常有两种选择:
**方式一:定义临时变量(最常见)**
```go
n := 42
p := &n
```
**方式二:写一个辅助函数(甚至有专门的库干这事)**
```go
func IntPtr(v int) *int { return &v }
p := IntPtr(42)
```
对于结构体,我们可以用 `&Person{Name: "Alice"}`,但对于 `int`、`string`、`bool` 这种简单类型,这种不对称性一直让很多追求代码简洁的开发者感到不适。
------
## **2. 进化:`new(expr)` 来了**
在即将到来的 Go 1.26 中,内置函数 `new` 将被赋予"超能力"。
以前: new(T) 只能接受一个类型,并返回该类型零值的指针。
现在: new(expr) 可以接受一个表达式,它会分配内存,将表达式的值存入其中,并返回指针。
#### **代码对比:**
**简单类型:**
```go
// Go 1.26 之后
p1 := new(42) // *int, 值为 42
p2 := new("go") // *string, 值为 "go"
```
**复合值(代替 & 符号):**
```go
// 以前
p := &[]int{1, 2, 3}
// 现在(更统一的写法)
p := new([]int{1, 2, 3})
```
函数返回值:
以前我们需要先用变量接收函数返回值再取地址,现在可以一步到位:
```go
f := func() string { return "hello" }
// Go 1.26 直接取回函数结果的指针
p := new(f())
```
------
## **3. 核心规则**
根据提案描述,`new` 的工作逻辑现在分为两条线:
1. **如果参数是表达式 `expr`(类型为 `T`):** `new(expr)` 分配一个类型为 `T` 的变量,用 `expr` 的值初始化它,返回其地址(`*T`)。
2. **如果参数是类型 `T`:** 保持现状,分配一个零值的 `T` 并返回地址。
> **注意:** `new(nil)` 依然是不允许的,因为 `nil` 没有明确的默认类型,会导致编译错误。
------
## **4. 为什么要这样改?**
这次改进的核心动力在于**一致性**。
Go 语言的设计者(包括 Alan Donovan, Ian Lance Taylor, Rob Pike 等)认为:
- **统一体验:** 让基本类型和复合类型在获取指针时的心智负担达成一致。
- **消除冗余:** 减少为了取地址而不得不定义的临时变量,让代码流更清晰。
- **兼容性:** 这是一个向后兼容的改动,现有的 `new(T)` 代码完全不受影响。
------
## **5. 什么时候能用上?**
该特性目前标记为 **Go 1.26**。虽然离正式发布还有一段时间,但它已经被列入 "Accepted" 状态,意味着语法规范已经定稿。
这是 Go 语言近年来在保持"简约"哲学的同时,不断吸收开发者反馈、优化编码效率的又一例证。
**你觉得这个改动实用吗?你更倾向于用 `&` 还是 `new`?欢迎在评论区留言讨论!**
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信148 次点击
添加一条新回复
(您需要 后才能回复 没有账号 ?)
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传