首页/文章/Golang

Golang面试题:new 和 make 有什么区别

2024-09-10
17976 分钟
...

今天我们来聊聊一个大家面试中经常遇到的问题:Golang 中的 new 和 make 到底有什么区别?这两货看起来名字差不多,但用法和场景可大不一样。为了方便大家理解,我来掰扯掰扯。

先说 new
这个函数名字虽然简单,但功能还挺关键。new 是 Go 语言的内置函数,它的作用就是分配内存,然后返回指向该内存地址的指针。

通俗点讲,new 干的事情就是帮你“造个房子”,不过它不负责装修,也就是只提供一个空的空间。这就意味着你通过 new 创建的对象,只是分配了内存,没有初始化内容,默认值是零值。

举个例子吧,new(int) 会返回一个指向 0 的指针,而 new([]int) 则会返回一个指向空 slice 的指针。

那 make 呢?

它也是 Go 的内置函数,但它比 new 功能更多,不仅帮你分配内存,还顺手把房子装修好,给你提供一个能直接使用的 slice、map 或 channel。

这里要注意了,make 只能用于 slice、map 和 channel 这三种引用类型。就像一个包工头,make 不但帮你建了房子,还把家具摆好,水电全都接通了,直接拎包入住。比如,make([]int, 10) 会创建一个长度为 10 的 slice,并且可以直接使用。

看到了吧?new 和 make 的区别就在这:new 是给你一个空的房间指针,你得自己来填充内容;而 make 是给你一个已经装修好的房间,可以直接用。new 主要用于结构体或数组这种值类型的指针分配,而 make 则是专门服务于 slice、map 和 channel。

既然我们在讲 Go 语言的内置函数,那顺便提一下格式化输出吧,很多人对 Printf、Sprintf 和 Fprintf 这三兄弟也分不清。其实,它们的区别主要在于输出的“目的地”不同。

先说 Printf

这个函数最常用,它的输出目标是标准输出,也就是你的屏幕。比如你在调试的时候,fmt.Printf("Hello, %s", "world") 就会在屏幕上输出“Hello, world”。

再说 Sprintf

这个函数和 Printf 的格式化功能一样,但它不是直接往屏幕上输出,而是返回一个格式化好的字符串,适合你把结果存在变量里再做其他处理。比如 s := fmt.Sprintf("Hello, %s", "world"),会把“Hello, world”存在字符串变量 s 中。

最后是 Fprintf

它则是把格式化后的字符串输出到指定的地方,通常是文件或者其他 IO 设备,比如你想把日志写到文件里,可以用 fmt.Fprintf(file, "Log entry: %d", 1)。

说完这些基础函数,咱们再来说点面试中的“坑”

我之前面试时碰到一个很经典的考点:面试官让你用 new 创建一个 slice,你怎么回答?

一般来说,这种问题是挖了坑等你跳的,因为 new([]int) 虽然返回了 slice 的指针,但这个 slice 并不能用,它只是一个空壳子,啥都没有。真正想用 slice,你还是得用 make,比如 make([]int, 0) 这样才能得到一个可以添加元素的 slice。

再举个例子,创建 map 的时候也是同样道理。new(map[string]int) 只能得到一个空 map 的指针,而 make(map[string]int) 则是直接返回一个可以用的 map。

因此,在开发中,尽量用 make 来初始化 slice、map 或 channel,因为它们都是引用类型,需要内存分配和初始化才能正常工作。

从这个例子也可以看出,new 和 make 的使用场景真的差别很大。new 更像是为你准备了个空模板,得靠你自己去填充;而 make 是直接给你一个完整的实例,拎包入住。所以面试时千万别把这俩搞混了,特别是在需要实际操作 slice、map 和 channel 的时候,一定要用 make 来搞定。

总结

new 更适合用于分配指针类型,而 make 是专门为 Go 语言中的三种引用类型服务的。如果你面试的时候遇到这些问题,记得先问问自己:“我只是要个空指针,还是想要一个可以用的实例?”这句话就能让你对 new 和 make 的使用瞬间清晰。

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
Golang2026-04-10
golang文档
1\. Go 是什么 Go 是一种 强类型、垃圾回收、原生支持并发 的编程语言。代码由 package 组成;用 module 管理依赖;可执行程序通常从 package main 的 main() 函数开始运行。Go 官方一直强调兼容性,Go 1.26 也继续保持 Go 1 的兼容承诺。 最小可运行程序: 这里你已经看到了 Go 最核心的 3 个语法点: package 声明包、import 导入包、func 声明函数。main 包里...
学习
Golang2025-07-11
Go语言strconv包:字符串和数值类型的相互转换
在实际开发中我们往往需要对一些常用的数据类型进行转换,如 string、int、int64、float 等数据类型之间的转换,Go语言中的 strconv 包为我们提供了字符串和基本数据类型之间的转换功能。 strconv 包中常用的函数包括 Atoi()、Itia()、parse 系列函数、format 系列函数、append 系列函数等,下面就来分别介绍一下。 string 与 int 类型之间的转换 字符串和整型之间的转换是我们平...
学习
Golang2025-06-11
深入理解 Go 中的 new() 和 make() 函数
在 Go 语言中, 和 是两个常用的函数,用于创建和初始化不同类型的变量。本文将深入探讨 和 的区别、使用场景以及底层实现原理。 引言 Go 中的 和 函数是用于创建和初始化变量的重要工具。 用于创建指定类型的零值变量,并返回该变量的指针。 用于创建并初始化引用类型的变量,如切片、映射和通道。 函数 函数的基本语法及用法。 创建的变量是指定类型的零值,并返回该变量的指针。 适用于创建引用类型以外的其他类型变量。 函数 函数的基本语法及用...
学习
Golang2025-06-10
Ubuntu 升级 golang 版本完美步骤
一、删除旧的版本(可选) 二、下载最新版本 三、设置环境变量 1、打开profile: 2、添加以下变量: 3、是环境立即生效 4、将环境立即生效载入脚本 先打开文件这个文件: 加入这个命令: 四、查看 go 环境变量 五、GO111MOUDLE和更改GOPROXY 六、查看 go 版本 ⚙️
学习
Golang2025-06-05
Go 自动升级依赖版本
🚀 Go 自动升级依赖版本 在 Go 语言项目中,依赖管理使用 Go Modules ( 和 )。如果想要 自动升级依赖 ,可以使用以下方法。 1\. 方式 1:升级所有依赖 🔹 作用: :升级所有 Go 依赖到最新的 次要版本(minor)或补丁版本(patch) 。 :升级所有项目内的依赖。 2\. 方式 2:升级指定依赖 🔹 作用: 只升级 这个依赖到最新版本。 如果你需要升级到 最新的主要版本(major version)...
学习
Golang2025-06-02
GO项目的打包和部署
在 Go 语言中,打包和部署应用非常简单,因为 Go 编译生成的可执行文件不依赖外部环境。以下是 打包发布和部署 Go 应用 的几种常见方式,以及一些最佳实践。 1\. 基本的打包和构建 构建可执行文件 你可以通过 命令将你的应用打包成一个可执行文件: 说明: 指定输出的可执行文件名(如果省略,输出名默认为当前目录名)。 如果没有错误,当前目录会生成一个可执行文件 (Windows 系统下是 )。 运行可执行文件: 2\. 打包不同平台...
学习

评论

请登录后发表评论

去登录
加载评论中...