【Golang】Golang进阶系列教程--Go 语言 new 和 make 关键字的区别

文章目录

  • 前言
  • new
    • 源码
    • 使用
  • make
    • 源码
    • 使用
  • 总结

前言

本篇文章来介绍一道非常常见的面试题,到底有多常见呢?可能很多面试的开场白就是由此开始的。那就是 new 和 make 这两个内置函数的区别。

在 Go 语言中,有两个比较雷同的内置函数,分别是 new 和 make 方法,其主要用途都是用于分配相应类型的内存空间。
看上去 new 和 make 都是分配内存的,那他们有什么区别呢?这个细节点也成为了不少 Go 语言工程师的面试题之一,值得大家一看。

其实这个问题本身并不复杂,简单来说就是,new 只分配内存,而 make 只能用于 slice、map 和 chan 的初始化,下面我们就来详细介绍一下。

new

new 是一个内置函数,它会分配一段内存,并返回指向该内存的指针。
其函数签名如下:

源码

// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
func new(Type) *Type

从上面的代码可以看出,new 函数只接受一个参数,这个参数是一个类型,并且返回一个指向该类型内存地址的指针。
同时 new 函数会把分配的内存置为零,也就是类型的零值。

使用

使用 new 函数为变量分配内存空间:

p1 := new(int)
fmt.Printf("p1 --> %#v \n ", p1) //(*int)(0xc42000e250) 
fmt.Printf("p1 point to --> %#v \n ", *p1) //0var p2 *int
i := 0
p2 = &i
fmt.Printf("p2 --> %#v \n ", p2) //(*int)(0xc42000e278) 
fmt.Printf("p2 point to --> %#v \n ", *p2) //0

上面的代码是等价的,new(int) 将分配的空间初始化为 int 的零值,也就是 0,并返回 int 的指针,这和直接声明指针并初始化的效果是相同的。

当然,new 函数不仅能够为系统默认的数据类型分配空间,自定义类型也可以使用 new 函数来分配空间,如下所示:

type Student struct {name stringage int
}
var s *Student
s = new(Student) //分配空间
s.name = "zhangsan"
fmt.Println(s)

这就是 new 函数,它返回的永远是类型的指针,指针指向分配类型的内存地址。需要注意的是,new 函数只会分配内存空间,但并不会初始化该内存空间。

make

make 也是用于内存分配的,但是和 new 不同,它只用于 slice、map 和 chan 的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型。因为这三种类型本身就是引用类型,所以就没有必要返回他们的指针了。
其函数签名如下:

源码

// The make built-in function allocates and initializes an object of type
// slice, map, or chan (only). Like new, the first argument is a type, not a
// value. Unlike new, make's return type is the same as the type of its
// argument, not a pointer to it. The specification of the result depends on
// the type:
// Slice: The size specifies the length. The capacity of the slice is
// equal to its length. A second integer argument may be provided to
// specify a different capacity; it must be no smaller than the
// length, so make([]int, 0, 10) allocates a slice of length 0 and
// capacity 10.
// Map: An empty map is allocated with enough space to hold the
// specified number of elements. The size may be omitted, in which case
// a small starting size is allocated.
// Channel: The channel's buffer is initialized with the specified
// buffer capacity. If zero, or the size is omitted, the channel is
// unbuffered.
func make(t Type, size ...IntegerType) Type

通过上面的代码可以看出 make 函数的 t 参数必须是 slice、map 和 chan 中的一个,并且返回值也是类型本身。

使用

下面用 slice 来举一个例子:

var s1 []int
if s1 == nil {fmt.Printf("s1 is nil --> %#v \n ", s1) // []int(nil)
}s2 := make([]int, 3)
if s2 == nil {fmt.Printf("s2 is nil --> %#v \n ", s2)
} else {fmt.Printf("s2 is not nill --> %#v \n ", s2)// []int{0, 0, 0}
}

slice 的零值是 nil,但使用 make 初始化之后,slice 内容被类型 int 的零值填充,如:[]int{0, 0, 0}。
map 和 chan 也是类似的,就不多说了。

总结

通过以上分析,总结一下 new 和 make 主要区别如下:

  • make 只能用来分配及初始化类型为 slice、map 和 chan 的数据。new 可以分配任意类型的数据;
  • new 分配返回的是指针,即类型 *Type。make 返回类型本身,即 Type;
  • new 分配的空间被清零。make 分配空间后,会进行初始化;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/14097.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

忽略nan值,沿指定轴计算标准(偏)差numpy.nanstd()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 沿指定轴方向 计算标准(偏)差 numpy.nanstd() [太阳]选择题 import numpy as np a np.array([[1,2],[np.nan,3]]) print("【显示】a ") print(a) print("【执行】np.std(a)&qu…

微信小程序:生成二维码带参数并获取值

通过后台接口可以获取小程序任意页面的小程序码,需要注意的是接口只能生成已发布的小程序的二维码 小程序接口文档 获取 scene 值 1)scene 字段的值会作为 query 参数传递给小程序/小游戏。用户扫描该码进入小程序/小游戏后,开发者可以获取…

链表OJ题目1 (移除链表元素)

力扣(链接放这里喽) 先贴代码再做讲解: struct ListNode* removeElements(struct ListNode* head, int val) {struct ListNode* cur head;struct ListNode* tail NULL;while(cur){if(cur->val val){if(cur head){head head->next…

「问题」如何解决 MyBatis 中的 if 标签无法识别参数为 0 的问题

如何解决 MyBatis 中的 if 标签无法识别参数为 0 的问题 如何让参数为0也能进入if标签的方法中?1、问题2、原因3、怎么解决这个问题? 如何让参数为0也能进入if标签的方法中? 1、问题 mybatis中的自己写的判断方法,若参数buildin…

react map使用方法详解

在React中,map()方法是用于数组的常见方法之一,它可以用于处理数组并返回一个新的数组。在React中,经常使用map()方法来遍历数组,生成对应的组件列表或进行数据转换操作。 下面是map()方法在React中的使用方法详解: …

chatGPT 学习分享:内含PPT分享下载

InstructGPT论文地址: Training language models to follow instructions with human feedbackchatGPT地址:openAI个人整理的PPT(可编辑),下载地址:chatGPT学习分享PPT

阿里巴巴 arthas的MathGame源码是什么

阿里巴巴开源的arthas是一个非常优秀的在线调试工具,为了方便学习者练习,提供了一个demo程序MathGame,并且发布在github中,不过呢,国内有时打不开,此时我们可以使用源码直接在我们的idea中启动,…

JUC并发编程之等待唤醒机制

目录 1. 线程等待唤醒机制 1.1 使用Object的wait()和notify()方法 1.2 使用Condition接口 1.3 使用LockSupport类 1. 线程等待唤醒机制 在JUC(Java Util Concurrent)并发编程中,线程等待唤醒机制是实现线程之间协作和同步的重要手段。这…

AIGC(Artificial Intelligence and Graph Computing)职业发展路径和前景如何?

目录 一、AIGC 基本概念二、AIGC 市场规模三、AIGC 未来发展前景四、AIGC 职业发展路径五、AIGC 技能要求六、AIGC 相关公司 AIGC(Artificial Intelligence and Graph Computing)是人工智能和图计算的结合,它是一种用于处理大规模复杂数据的计…

暑假刷题第16天--7/28

143. 最大异或对 - AcWing题库&#xff08;字典树&#xff09; #include<iostream> using namespace std; const int N100005; int a[N]; int nex[10000007][2],cnt; void insert(int x){int p0;for(int i30;i>0;i--){int ux>>i&1;if(!nex[p][u])nex[p][u]…

java排序算法之插入排序

文章目录 &#x1f4cb;插入排序概念&#x1f4d6;实现步骤&#x1f516;代码示例 &#x1f4c8;总结 &#x1f4cb;插入排序概念 插入排序&#xff08;Insertion Sort&#xff09;是一种简单直观的排序算法。它将数组划分为已排序和未排序两个部分&#xff0c;每次从未排序部分…

Linux 多线程并发Socket服务端的实现( 11 ) -【Linux通信架构系列 】

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 设计模式系列 期待你的关注哦&#xff01;&#xff01;&#xff01; 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everythi…

25.9 matlab里面的10中优化方法介绍—— 惩罚函数法求约束最优化问题(matlab程序)

1.简述 一、算法原理 1、问题引入 之前我们了解过的算法大部分都是无约束优化问题&#xff0c;其算法有&#xff1a;黄金分割法&#xff0c;牛顿法&#xff0c;拟牛顿法&#xff0c;共轭梯度法&#xff0c;单纯性法等。但在实际工程问题中&#xff0c;大多数优化问题都属于有约…

SpringBoot读取配置文件顺序

文章目录 一、前言二、SpringBoot配置文件目录读取顺序源码解析 三、SpringBoot配置文件类型读取顺序源码解析 一、前言 本文通过源码分析 SpringBoot 加载配置文件目录的顺序&#xff0c;以及 properties、xml、yml、yaml文件的读取顺序 二、SpringBoot配置文件目录读取顺序…

【MySQL】库的操作

废话不多说&#xff0c;直接上操作&#xff1a; 目录 一、查看数据库 二、创建数据库 2.1 数据库的字符集及校验规则 2.1.1 查看系统默认字符集 2.1.2 查看系统默认校验规则 2.1.3 查看数据库支持的字符集 2.1.4 查看数据库支持的校验规则 2.2 创建数据库时设置字符集和…

【二叉树进阶】搜索二叉树(递归+非递归两种版本详解)

文章目录 前言1. 二叉搜索树的概念2. 二叉搜索树的结构2.1 结点结构2.2 树结构 3. 插入操作&#xff08;非递归&#xff09;3.1 思路分析3.2 代码实现3.3 中序遍历&#xff08;测试用&#xff09; 4. 查找操作&#xff08;非递归&#xff09;4.1 思路分析4.2 代码实现 5. 删除操…

【设计模式】观察者设计模式解析

目录 一、观察者模式定义 二、观察者模式角色 三、观察者模式类图 四、观察者模式实例 五、观察者模式优缺点 5.1、优点 5.2、缺点 六、观察者模式应用 6.1、Spring 中观察者模式的四个角色 6.2、coding~~~~~~ 一、观察者模式定义 观察者模式(Observer Pattern)&#…

【如何训练一个中英翻译模型】LSTM机器翻译模型训练与保存(二)

系列文章 【如何训练一个中英翻译模型】LSTM机器翻译seq2seq字符编码&#xff08;一&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型训练与保存&#xff08;二&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型部署&#xff08;三&#xff09; 【如何训…

【框架篇】Spring Boot 日志

Spring Boot 日志 一&#xff0c;日志用途 尽管一个项目在没有日志记录的情况下可能能够正常运行&#xff0c;但是日志记录对于我们来说却是至关重要的&#xff0c;它存在以下功能&#xff1a; 1&#xff0c;故障排查和调试&#xff1a;当项目出现异常或者故障时&#xff0c;…

idea连接远程服务器上传war包文件

idea连接远程服务器&上传war包 文章目录 idea连接远程服务器&上传war包1. 连接服务器2.上传war包 1. 连接服务器 选择Tools -> Start SSH Session 添加配置 连接成功 2.上传war包 Tools -> Deployment -> Browse Remote Host 点击右侧标签&#xff0c;点击&…