前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go new vs make

Go new vs make

作者头像
Dylan Liu
发布2019-07-01 12:00:18
4090
发布2019-07-01 12:00:18
举报
文章被收录于专栏:dylanliu

摘要

Go 提供了两个关键字newmake 来为类型分配内存,但两者的功能是不同的,一句话来说就是:new只管 内存分配,而make用来初始化slice,map 和 channel

new

原型:func new(Type) *Type

Go 官方文档上的解释:

代码语言:javascript
复制
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.

这里我们关注到一点 newly allocated zero value of that type, 也就是说new 分配内存之后,会返回对应类型为零值的指针,它的参数是一个类型,这个类型在这里是一个占位符,可以看到它的定义为type Type int , 我们在应用程序里是获取不到的(一直在这有疑惑,Go 的包规范要求首字母大写的是public的,小写的是private的,但是在builtin 包中,小写的可以在程序中使用,大写的反而是不可用的)。

make

原型:func make(t Type, size ...IntegerType) Type

Go 官方文档解释:

代码语言:javascript
复制
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:

make 只能用来创建 slice,map 和channel,并不能用于其他类型,当然我们可以看到 make 和 new 的函数签名是类似的,但是当使用 int 等类型作为 make 参数时,编译会报错。

make还可以接收整形参数来决定初始容量,slice 第一个参数代表len,第二个代表 capacity,map 只能有一个参数代表初始容量,channel 的 int 参数代表 buffer 大小(没有代表无缓冲)

为什么需要用 make 来创建这三个类型?因为这三个类型代表的是对数据结构的引用,要使用它们,必须要先初始化。以slice 为例,一个 slice 需要3 个元素:指向数据的指针,长度(len)和容量(cap)(有疑问的可以参见 go slice usage), 在未初始化之前slice 为nil,是不可用的。也就是说 对slice、map、channel 三种类型,make初始化了它们的内部数据结构,使得它们立即可用。

对比

new 对于接收的参数类型是没有限制的,也即我们可以传slice、map、channel类型,表面上看new 的存在就够了,但是,我们要知道,这个new 出来的slice、map、channel 为nil,实际上没有用处,对于接口也一样,new 可以接收,但返回 nil,在程序中是不可用的。

为何要有两个函数

这个问题在网上也有很多讨论,问题的真正答案只有 Go 语言的发明人才能给出。我们这里只作猜测。

与这个问题对等的是如果只有一个分配函数会怎么样?

假设我们的新分配函数名字叫alloc, 参数只能与 make 一样,因为我们既需要能处理 int 这种不需要长度的类型,也需要处理 slice 这种需要长度的类型,然后返回类型为指针(只能有一种返回类型,分配到堆上返回指针),我们来看一下它的使用问题。

  1. 参数冗余

size ...IntegerType 参数在为基本类型时是多余的,就算传递了,也是不用的,这是一种设计缺陷。按照我们在其他编程语言里的编程实践,遇到这种问题时,我们会使用方法重载,但 Go 中不支持函数重载,此路不通。

  1. 返回类型为指针,slice等使用麻烦

使用 make 返回的是类型本身,如果返回的是指针的话,我们使用起来就需要多加一层括号,获取 slice 中的某一个元素需要这样使用(*slice)[i], map 也是一样,会引起不必要的解引用

从语言设计者的角度来看,设计一个函数槽点太多,索性分开为两个,权责明确,使用方便,而且这不又给了很多人写博客的一个话题嘛。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 摘要
  • new
  • make
  • 对比
  • 为何要有两个函数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档