0

0

Go 中 new(T) 与 &T{} 的本质区别及使用建议

聖光之護

聖光之護

发布时间:2026-01-14 10:32:18

|

892人浏览过

|

来源于php中文网

原创

Go 中 new(T) 与 &T{} 的本质区别及使用建议

`new(t)` 和 `&t{}` 都在运行时分配内存并返回指针,但语义和适用场景不同:前者仅支持零值初始化且适用于所有类型,后者支持自定义字段初始化且仅适用于可字面量化的复合类型(如 struct、slice、map 等)。

在 Go 中,new(T) 和 &T{} 确实都会为类型 T 分配堆内存(或由编译器优化到上),并返回指向该内存的 *T 指针。表面看功能重叠,但二者在语言设计、使用惯用法和实际约束上存在关键差异。

✅ 语义与能力对比

  • new(T):

    • 总是返回指向零值的指针
    • 适用于任意类型:new(int)、new(string)、new([3]int)、new(func()) 均合法;
    • 不支持字段初始化,无法指定初始值;
    • 底层等价于声明一个匿名变量再取地址:var t T; return &t。
  • &T{...}(复合字面量取址):

    • 仅适用于可构造字面量的类型:struct、array、slice、map、channel、func(需显式签名);
    • 支持显式初始化:&struct{X, Y int}{1, 2}、&[]int{1,2,3}、&map[string]int{"a": 1};
    • 若省略字段(即 &T{}),则各字段按零值初始化,效果 看似 等同 new(T),但底层实现和可读性更优。
// ✅ 合法且推荐:结构体带初始化
s := &struct{ Name string; Age int }{"Alice", 30}

// ✅ 合法:零值结构体(更清晰表达意图)
s0 := &struct{ Name string; Age int }{}

// ✅ 合法:基础类型只能用 new
pInt := new(int)     // 等价于 var x int; pInt := &x
pFunc := new(func()) // 唯一可行方式获取 func 类型指针

// ❌ 编译错误:基础类型不支持字面量取址
// bad := &int{}      // syntax error: cannot take address of int{}
// bad := &string{}   // same

⚠️ 实际使用建议

  • 优先使用 &T{...}:对 struct、slice、map 等,它更直观、可读性强,且支持初始化,是 Go 社区公认的惯用写法(idiomatic Go)。
  • new(T) 使用场景极窄
    • 当你需要一个指向零值的指针,且 T 是基础类型(如 int、bool)或函数类型,而 &T{} 不可用时;
    • 极少数泛型或反射场景中需统一类型构造逻辑(但通常有更优替代方案)。
  • 多数情况下,应避免显式分配指针
    Go 编译器具备逃逸分析能力,能自动决定变量分配在栈还是堆。直接声明值再取址往往更简洁、安全:
// ? 不必要地强调“堆分配”
p := new(int)
*p = 42

// ? 更自然、更符合 Go 风格
x := 42
p := &x // 编译器自动决策 x 是否逃逸

? 总结

new(T) 并非冗余,而是为类型系统完整性所保留的底层原语;但它在日常开发中极少出现——Go 的设计哲学是“显式优于隐式,简洁优于繁琐”。当你看到 new(T),应首先思考:是否真的需要它?能否用 &T{...} 替代?或者干脆用值语义 + 编译器优化?答案通常是后者。掌握这一区别,有助于写出更地道、更易维护的 Go 代码。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

537

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

52

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

194

2025.08.29

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

387

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

571

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

387

2023.07.18

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

0

2026.01.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.7万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号