网上有相当的的文章讲述,但是还是不太理解,可以通俗的讲下之间的区别吗
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 ![]() 一句话概括: 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 ![]() ### 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 等值类型,返回值是分配的地址的指针 ``` |