Go语言中的内建函数new和make是两个用于内存分配的原语(allocation primitives),其功能相似,却有本质区别。

1、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(t)分配了零值填充的类型为T内存空间,并且返回其地址,即一个*t类型的值。返回的永远是类型的指针,指向分配类型的内存地址

它并不初始化内存,只是将其置零。*t指向的内容的值为零(zero value)。注意并不是指针为零。

2、make

官方文档

//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.func make(t Type, size ...IntegerType) Type

翻译如下:

内建函数 make 用来为 slice,map 或 chan 类型分配内存和初始化一个对象(注意:只能用在这三种类型上),跟 new 类似,第一个参数也是一个类型而不是一个值,跟 new 不同的是,make 返回类型的本身而不是指针,而返回值也依赖于具体传入的类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了

make(t, args)与new(t)的功能区别是,make只能创建slice、map和channel,并且返回一个初始化的类型为t的值(而不是*t)。

注意,因为这三种类型是引用类型,所以必须得初始化,但是 不是置为零值,这个和new是不一样的。

3、为什么slice、map和channel要由make创建呢?

先来看一下以上三个数据结构的源码

slice

type slice struct {array unsafe.Pointerlen intcap int
}

slice的结构体由3部分构成,Pointer 是指向一个数组的指针,len 代表当前切片的长度,cap 是当前切片的容量。

map

// A header for a Go map.
type hmap struct {count int flags uint8B uint8 noverflow uint16 hash0 uint32 buckets unsafe.Pointer oldbuckets unsafe.Pointer nevacuate uintptr extra *mapextra
}

channel

type hchan struct {qcount uint dataqsiz uint buf unsafe.Pointerelemsize uint16 closed uint32 elemtype *_type sendx uint recvx uint recvq waitq sendq waitq lock mutex
}

看到没有,都是需要分配内存的

4、总结

new和make都在堆上分配内存,但是它们的行为不同,适用于不同的类型。

new(T) 为每个新的类型T分配一片内存,初始化为 0 并且返回类型为*T的内存地址:这种方法 返回一个指向类型为 T,值为 0 的地址的指针,它适用于值类型如数组和结构体;它相当于 &T{}。

make(T) 返回一个类型为 T 的初始值,是三个引用类型本身,它只适用于3种内建的引用类型:slice、map 和 channel。

换言之,new 函数分配内存,make 函数初始化;

其实new不常用

所以有new这个内置函数,可以给我们分配一块内存让我们使用,但是现实的编码中,它是不常用的。我们通常都是采用短语句声明以及结构体的字面量达到我们的目的,比如:

i:=0
u:=user{}

这样更简洁方便,而且不会涉及到指针这种比麻烦的操作。

make函数是无可替代的,我们在使用slice、map以及channel的时候,还是要使用make进行初始化,然后才才可以对他们进行操作。

package mainimport ("fmt"
)func main() {p := new([]int) //p == nil; with len and cap 0fmt.Println(p)v := make([]int, 10, 50) // v is initialed with len 10, cap 50fmt.Println(v)/*********Output****************&[][0 0 0 0 0 0 0 0 0 0]*********************************/(*p)[0] = 18        // panic: runtime error: index out of range// because p is a nil pointer, with len and cap 0v[1] = 18           // ok}

  

转载于:https://www.cnblogs.com/chenpingzhao/p/9918062.html

【go】golang中置new()函数和make()函数的区别相关推荐

  1. Golang中int, int8, int16, int32, int64和uint区别

    Golang中int, int8, int16, int32, int64和uint区别 前言 测试 结果 结论 总结 前言 在学习go语言时,做算法题会很经常遇到go语言的各种int类型,为什么会有 ...

  2. Golang中uint、int, int8, int16, int32, int64区别

    Golang各种数值占据的大小 int类型的大小为 8 字节 int8类型大小为 1 字节 int16类型大小为 2 字节 int32类型大小为 4 字节 int64类型大小为 8 字节 ====== ...

  3. golang中string长度

    golang中计算string长度用len函数,但是len函数返回的是字符串的 byte 数量 如果要得到字符串的字符数,可使用 "unicode/utf8" 包中的 RuneCo ...

  4. Golang中支持可变参数

    Golang中支持可变参数 (如果你希望函数带有可变数量的参数) package main import "fmt" //定义一个函数,函数的参数为:可变参数 ... 参数的数量可 ...

  5. golang 中 map 排序

    golang 中没有专门的 map 排序函数,且 map 默认是无序的,也就是你写入的顺序和打印的顺序是不一样的. m := make(map[string]string, 0) m["on ...

  6. Golang中 int int8 int16 int32 int64的区别和取值范围

    先说结论吧,方便快速查询验证. 总结 区别 int 类型大小为 8 字节 int8 类型大小为 1 字节 int16 类型大小为 2 字节 int32 类型大小为 4 字节 int64 类型大小为 8 ...

  7. golang的new函数_new()和make()函数以及Golang中的示例

    golang的new函数 In Golang, to allocate memory, we have two built-in functions new() and make(). 在Golang ...

  8. Golang 内置函数

    Golang中内置了一些函数,在使用这些函数时,不必以包名为前缀来调用,而是直接写函数名即可调用,这些函数都是一些基础的函数,在程序设计中应用比较普遍,所以一定要牢记这些最基本的函数用法.下边来介绍一 ...

  9. GoLang之内置len、cap函数

    文章目录 GoLang之内置len.cap函数 1.len函数 2.cap函数 GoLang之内置len.cap函数 1.len函数 len 函数用于返回传入参数的长度; len可以传入的参数有: 1 ...

最新文章

  1. [转]英文版VS2010制作中文环境安装包
  2. 12个不可不知的Sublime Text应用技巧和诀窍
  3. 扬州大学计算机专业考研分数线,扬州大学2021考研分数线已公布
  4. 2021年阳光高考成绩查询,高考攻略 | 2021年阳光高考月历来了!
  5. Rinne Loves Xor
  6. 安卓逆向_8 --- Android 调试工具 DDMS 和 Monitor ( 去掉 车来了 app 的广告 )
  7. Python案例:用米粒填充国际象棋盘
  8. 阿里天池全国社保比赛心得
  9. linux安装jdk8和tomcat8
  10. 【 BlockChain 】零知识证明
  11. librosa 音频处理库
  12. 单招软件职业技能测试,招生信息网-2019年单独招生《职业技能测试》考试大纲...
  13. Python爬虫之实习僧招聘信息及数据分析
  14. 自定义拖动条android,Android自定义滑动带(横条指示器)
  15. 思科 交换机 全局、telnet、consol 密码配置
  16. React-native项目使用逍遥游模拟器运行
  17. 每晚夜里自我独行,随处荡,多冰冷,以往为了自我挣扎
  18. HTML基础DW使用教程
  19. 豆制品加工黄浆水污水处理设备工艺特色
  20. 【操作系统】实验六 系统内存使用统计

热门文章

  1. CSS中常用的10个文本样式属性——让文本设置再无难点
  2. 使用golang发送电子邮件
  3. 信息系统项目管理:项目经理担任什么样的角色?
  4. 在HTML中可以链接Word文档吗,网页用word打开-可以直接打开word文件的超链接在网页中, – 手机爱问...
  5. Manage images
  6. linux手动连接网络打印机驱动_怎么在Linux上安装打印机驱动
  7. TWS耳机背后的推手
  8. 2022海康威视秋招内推(最新)
  9. c语言程序编译与烧录,一种解释自定义脚本并烧录的方法与流程
  10. DB2DIAG 命令学习