博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Go new vs make
阅读量:6207 次
发布时间:2019-06-21

本文共 1998 字,大约阅读时间需要 6 分钟。

  hot3.png

摘要

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

new

原型:func new(Type) *Type

Go 官方文档上的解释:

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 newlyallocated 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 官方文档解释:

The make built-in function allocates and initializes an object of typeslice, map, or chan (only). Like new, the first argument is a type, not avalue. Unlike new, make's return type is the same as the type of itsargument, not a pointer to it. The specification of the result depends onthe type:

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

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

为什么需要用 make 来创建这三个类型?因为这三个类型代表的是对数据结构的引用,要使用它们,必须要先初始化。以slice 为例,一个 slice 需要3 个元素:指向数据的指针,长度(len)和容量(cap)(有疑问的可以参见 ), 在未初始化之前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 也是一样,会引起不必要的解引用

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

转载于:https://my.oschina.net/liufq/blog/1939613

你可能感兴趣的文章
有关MSHTML
查看>>
让自己的头脑极度开放
查看>>
我的友情链接
查看>>
前端优化实例
查看>>
review what i studied `date` - 2017-3-31
查看>>
Adding text to Access Gateway (AGEE) Enterprise Logon Page
查看>>
一些会用到的知识
查看>>
用脚本控制虚拟机
查看>>
DUMPE2FS(8)
查看>>
Puppet 之 模板和模块
查看>>
Suse 12 安装VMware tool
查看>>
《C++程序设计原理与实践》读书笔记(二)
查看>>
计算机类产品评价技术指标体系研究之图形(像)篇
查看>>
域名商2014年度报告:35互联域名总量增至33.4万
查看>>
2月份Web服务器份额:排名不变 仅Microsoft份额上扬
查看>>
在Spring boot 配置过滤器(filter)
查看>>
vrrp
查看>>
Python 练习册,每天一个小程序
查看>>
由旋转矩阵求旋转中心
查看>>
89. Gray Code - LeetCode
查看>>