深入理解Golang中的new和make函数


在 Go 语言开发中,new() 和 make() 是两个容易让开发者感到困惑的内建函数。尽管它们都用于内存分配,但其设计目的、适用场景和底层实现存在本质差异。
本文将通过类型系统、内存模型和编译器实现三个维度,深入解析这两个函数的本质区别。

一、类型系统的哲学分野

1.1 new() 的通用性设计

new(T) 是为所有类型设计的通用内存分配器,其行为模式高度统一:

// 为 int 类型分配零值内存
pInt := new(int)  // *int 类型

// 为自定义结构体分配内存
type MyStruct struct {
   
    a int }
pStruct := new(MyStruct) // *MyStruct 类型

其核心特征:

  • 返回类型始终为 *T
  • 分配的内存被初始化为类型零值
  • 适用于任何类型(包括基本类型、结构体、数组等)

1.2 make() 的特化使命

make() 是 Go 为特定引用类型设计的构造器:

// 创建 slice
s := make([]int, 5, 10) 

// 初始化 map
m := make(map[string]int)

// 建立 channel
ch := make(chan int, 5)

关键限制:

  • 仅适用于 slice、map 和 channel 三种类型
  • 返回已初始化的类型实例(非指针)
  • 支持类型特定的初始化参数

二、内存模型的实现差异

2.1 new() 的底层机制

当编译器遇到 new(T) 时:
1.计算类型大小:size = unsafe.Sizeof(T{})
2.调用 runtime.newobject 分配内存
3.执行内存清零操作(对应零值初始化)
4.返回指向该内存的指针

以下伪代码示意其过程:

func new(T) *T {
   
   
    ptr := malloc(sizeof(T))
    *ptr = T{
   
   }  // 零值初始化
    return ptr
}

2.2 编译器前端的语法解析

// 原始代码片段
type MyStruct struct {
   
    a int }
p := new(MyStruct)

// 转换为中间表示 (IR)
ptr := runtime.newobject(unsafe.Pointer(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水草

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值