当前位置: 首页 > ops >正文

Go 面试题: new 和 make 是什么,差异在哪?

在 Go 语言中,有两个比较雷同的内置函数,分别是 newmake 方法,其主要用途都是用于分配相应类型的内存空间。

在 Go 语言中,newmake 都是用于内存分配的关键字,但它们的用途和行为有所不同。理解这两者的差异,对于编写高效且可维护的 Go 代码至关重要。本文将详细解释这两者的含义、用法以及它们之间的区别。

一、new 关键字

new 关键字用于为某个类型分配内存并返回该类型的指针。

看上去 newmake 都是分配内存的,那他们有什么区别呢?这个细节点也成为了不少 Go 语言工程师的面试题之一,值得大家一看。

在这篇文章中我们将来解答这个问题。

基本特性

make

在 Go 语言中,内置函数 make 仅支持 slicemapchannel 三种数据类型的内存创建,其返回值是所创建类型的本身,而不是新的指针引用

函数签名如下:

func make(t Type, size ...IntegerType) Type

具体使用示例:

func main() {v1 := make([]int, 1, 5)v2 := make(map[int]bool, 5)v3 := make(chan int, 1)fmt.Println(v1, v2, v3)
}

在代码中,我们分别对三种类型调用了 make 函数进行了初始化。你会发现有的入参是有多个长度指定,有的没有。

这块的区别主要是长度(len)和容量(cap)的指定,有的类型是没有容量这一说法,因此自然也就无法指定。

输出结果:

[0] map[] 0xc000044070

有一个细节点要注意,调用 make 函数去初始化切片(slice)的类型时,会带有零值,需要明确是否需要。

见过不少的小伙伴在这上面踩坑。

new

在 Go 语言中,内置函数 new 可以对类型进行内存创建和初始化。其返回值是所创建类型的指针引用,与 make 函数在实质细节上存在区别。

函数签名如下:

func new(Type) *Type

具体使用示例:

type T struct {Name string
}func main() {v := new(T)v.Name = "煎鱼"
}

从上面的例子的效果来看,是不是似曾相似?其实与下面这种方式的一样的:

func main() {v := T{}v.Name = "煎鱼"
}

输出结果均是:

&{Name:煎鱼}

其实 new 函数在日常工程代码中是比较少见的,因为他可被替代。

一般会直接用快捷的 T{} 来进行初始化,因为常规的结构体都会带有结构体的字面属性:

func NewT() *T {return &T{Name: "煎鱼"}
}

这种初始化方式更方便。

区别在哪里

可能会有的小伙伴会疑惑一点,就是 new 函数也能初始化 make 的三种类型:

v1 := new(chan bool)v2 := new(map[string]struct{})

make 函数的区别,优势是什么呢?

本质上在于 make 函数在初始化时,会初始化 slicechanmap 类型的内部数据结构,new 函数并不会。

例如:在 map 类型中,合理的长度(len)和容量(cap)可以提高效率和减少开销。

更进一步的区别:

  • make 函数:
    • 能够分配并初始化类型所需的内存空间和结构,返回引用类型的本身。
    • 具有使用范围的局限性,仅支持 channelmapslice 三种类型。
    • 具有独特的优势,make 函数会对三种类型的内部数据结构(长度、容量等)赋值。
  • new 函数:
    • 能够分配类型所需的内存空间,返回指针引用(指向内存的指针)。
    • 可被替代,能够通过字面值快速初始化。

三、new 和 make 的差异

  1. 用途不同

    • new 用于为某个类型分配内存并返回该类型的指针。适用于结构体、数组、切片、映射等类型的内存分配,但不负责初始化数据。
    • make 专门用于初始化切片、映射和通道。它会分配内存并且初始化这些数据结构。
  2. 返回值类型不同

    • new 返回的是类型的指针(*T),而 make 返回的是具体类型本身(例如,mapchan 或 []T)。
  3. 适用场景不同

    • new 适用于任何类型的内存分配,但不会初始化数据。它适用于需要指针的类型。
    • make 只适用于切片、映射和通道,它会初始化底层的数据结构。
  4. 初始化行为

    • new 分配的内存会被初始化为零值。例如,对于整数类型,new(int) 会分配一个值为 0 的内存。
    • make 会为切片、映射和通道分配内存并进行初始化。比如,对于 make([]int, 5),它不仅会分配一个长度为 5 的切片,还会初始化切片的元素。

四、总结

  • new:用于为任意类型分配内存,并返回指向该类型的指针。适用于结构体、数组等类型。返回值是指针,内存初始化为零值。
  • make:专门用于初始化切片、映射和通道,并返回相应的对象。适用于切片、映射、通道。返回值是对象本身,且已被初始化。

理解这两个关键字的差异,有助于我们更好地掌握 Go 语言的内存管理和数据结构初始化,从而编写更加高效和健壮的程序。

http://www.xdnf.cn/news/19402.html

相关文章:

  • ADSL 代理 Proxy API 申请与使用指南
  • NLP技术突破:浅层与深层语义分析全解析
  • test隐藏能力
  • 5-ATSAM3X8-定时器
  • 架构选型:为何用对象存储替代HDFS构建现代数据湖
  • 腾讯混元翻译大模型Hunyuan-MT-7B:重塑跨语言沟通的技术革命
  • 定时器设计之->分级时间轮
  • 基于SpringBoot的二手交易平台【2026最新】
  • 2025我“生发”了『折行』|『内注』|『终端正偿』|『中文负偿』四大“邪术”(前二造福python代码阅读者;后二助力所有艺术人)
  • Kali自带的录屏工具:recordmydesktop
  • 基于单片机电动车充电桩/充电车棚环境监测设计
  • 如何将照片从电脑传输到安卓设备
  • vscode翻译插件
  • Kafka 架构原理
  • 【大模型】大模型微调-RLHF(强化学习)
  • Certificate is Signed Using a Weak Signature Algorithm漏洞解决
  • Uniapp 图片前端上传功能实现与详解
  • JVM:内存区域划分、类加载的过程、垃圾回收机制
  • 【Spring Cloud微服务】8.深度实战:微服务稳定性的守护神——Sentinel
  • 项目升级--mysql主从复制和读写分离
  • 统计学的“尝汤原理”:用生活案例彻底理解中心极限定理
  • 9.1C++——类中特殊的成员函数
  • GitHub 热榜项目 - 日榜(2025-09-01)
  • Android面试指南(六)
  • 科学研究系统性思维的方法体系:数据收集模板
  • 【Docker】Docker的容器Container、镜像Image和卷Volume对比
  • JVM核心机制:类加载与内存结构详解
  • Axios与Ajax:现代Web请求大比拼
  • 彻底搞懂 C++ 中的 `typename`
  • datax将数据从starrocks迁移至starrocks