网上有相当的的文章讲述,但是还是不太理解,可以通俗的讲下之间的区别吗
1
wtysos11 2022-03-23 10:20:17 +08:00
之前看到的一篇文章,讲的挺好的:[面向信仰编程_make 和 new]( https://draveness.me/golang/docs/part2-foundation/ch05-keyword/golang-make-and-new/),最开头应该算 OP 要的通俗解释吧。
|
2
cmdOptionKana 2022-03-23 10:21:41 +08:00
一句话:make 只能用于 map 、slice 、channel ,new 只能用于结构体。
|
3
fgwmlhdkkkw 2022-03-23 10:24:06 +08:00
make 是 new 的扩展,仅支持 map 、slice 和 channel 。
|
4
fgwmlhdkkkw 2022-03-23 10:25:18 +08:00
@fgwmlhdkkkw #3 不对,它没有扩展 new ,,,😓
|
5
awanganddong OP make 关键字的作用是创建切片、哈希表和 Channel 等内置的数据结构,而 new 的作用是为类型申请一片内存空间
我是不是可以这样理解 所谓的 make 初始化就是給已经申请内存空间,一个特定的数据结构。 new 与 make 相比,缺少了所谓的初始化的过程。 |
6
mcfog 2022-03-23 10:32:51 +08:00
|
7
awanganddong OP @cmdOptionKana 你的意思是对用的数据类型不一致
|
8
Mohanson 2022-03-23 10:36:32 +08:00 4
一句话概括:
new: 在调用时编译器知道你需要使用多少内存, 例如结构体, 整形或浮点型. make: 在调用时编译器不知道你需要使用多少内存, 例如 slice, channel, map ... 这些数据结构占用的内存是运行时才能知晓的 |
9
bruce0 2022-03-23 10:36:35 +08:00
@cmdOptionKana new 只能用于结构体 new 不止可以用于结构体, 任何是指针的都可以 用 new
``` m := make(map[int]int) m[1] = 1 a := new(map[int]int) a = &m fmt.Println(*a) ``` 这段代码是没问题的 |
10
cmdOptionKana 2022-03-23 10:48:07 +08:00
@bruce0 可以是可以,但我觉得这类似 JavaScript 的隐性类型转换,有具体规则,但实际使用中提倡不要去研究这些细节,直接采用最佳实践。
|
11
ganbuliao 2022-03-23 10:51:38 +08:00
对普通的使用者来说只要知道一个是返回引用类型,一个是返回值类型的变量就可以了,要想更深入了解就看代码这两个方法是咋实现的呗。反正我目前还没有要看底层实现的需求。
|
12
zhijiangliu 2022-03-23 10:52:30 +08:00
1 make 用于创建内置复合类型(map, slice, channel),new 用于创建其他基础类型数据或用户自定义数据。
2 复合类型数据结构通常是一个结构体+堆内存,因此 make 的额外作用就是初始化这些数据(和指针)。从这一点看,make 的作用是申请内存,并且初始化数据。而 new 只负责申请内存,不初始化。 3 为什么 new 不会初始化,因为没有类似构造函数的概率。 4 虽然 make 是内置函数,但它并不是一个函数。golang 编译器在编译时,会根据 make 的参数类型选择相对应的运行时函数。例如 make(map[int]int), 那么就会将 make 替换成 new_map 之类的函数。 总结一下,make 用于创建内置复合类型数据,new 用于创建其他数据。 |
13
awanganddong OP @all 谢谢诸位,我理解理解
|
15
guanhui07 2022-03-23 12:18:01 +08:00
make 只能用于 map 、slice 、channel ,new 只能用于结构体。
|
16
tianyou666shen 2022-03-23 14:18:39 +08:00
make: 给 slice map channel 分配内存空间,返回这个值.注意这些类型是引用类型变量
new: 常用来初始化自己定义的结构体,创建对象,返回新建对象的引用 另外 make([]string,0,5) 可以指定 slice 的长度,容量, 一开始就能估算出容量可以减少后续一次次扩容的开销 make(chan,1) 可以创建有缓冲区的 channel |
17
jakehu 2022-03-23 21:14:43 +08:00
make 返回引用对象
new 返回指针对象 |
18
Joyreece 2022-03-24 01:42:05 +08:00 via iPhone 1
### new 、make
`**new()**` 函数用于为任何类型对象开辟内存空间的功能,其会将新开辟的内存空间设置为零值,然后返回这块内存区域的**指针**。 `**make()**` 函数仅用于 slice 、map 和 channel 类型的初始化使用,其会先开辟内存空间,然后再进行数据结构的必要的初始化(例如设置 cap 、size 等),最后返回初始化好的**实例对象本身**。 相关**官方文档:** - new:[https://go.dev/doc/effective_go#allocation_new]( https://go.dev/doc/effective_go#allocation_new) - make:[https://go.dev/doc/effective_go#allocation_make]( https://go.dev/doc/effective_go#allocation_make) |
19
lizuoqiang 2022-03-24 11:39:49 +08:00
```
- make 作用于 slice 、map 、channel ,返回值是这些类型的实例 - new 作用于 array 、struct 等值类型,返回值是分配的地址的指针 ``` |