V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
awanganddong
V2EX  ›  Go 编程语言

go make 与 new 关键词的区别

  •  1
     
  •   awanganddong · 257 天前 · 2358 次点击
    这是一个创建于 257 天前的主题,其中的信息可能已经有所发展或是发生改变。

    网上有相当的的文章讲述,但是还是不太理解,可以通俗的讲下之间的区别吗

    19 条回复    2022-03-24 11:39:49 +08:00
    wtysos11
        1
    wtysos11  
       257 天前
    之前看到的一篇文章,讲的挺好的:[面向信仰编程_make 和 new]( https://draveness.me/golang/docs/part2-foundation/ch05-keyword/golang-make-and-new/),最开头应该算 OP 要的通俗解释吧。
    cmdOptionKana
        2
    cmdOptionKana  
       257 天前
    一句话:make 只能用于 map 、slice 、channel ,new 只能用于结构体。
    fgwmlhdkkkw
        3
    fgwmlhdkkkw  
       257 天前
    make 是 new 的扩展,仅支持 map 、slice 和 channel 。
    fgwmlhdkkkw
        4
    fgwmlhdkkkw  
       257 天前
    @fgwmlhdkkkw #3 不对,它没有扩展 new ,,,😓
    awanganddong
        5
    awanganddong  
    OP
       257 天前
    make 关键字的作用是创建切片、哈希表和 Channel 等内置的数据结构,而 new 的作用是为类型申请一片内存空间


    我是不是可以这样理解
    所谓的 make 初始化就是給已经申请内存空间,一个特定的数据结构。
    new 与 make 相比,缺少了所谓的初始化的过程。
    mcfog
        6
    mcfog  
       257 天前
    awanganddong
        7
    awanganddong  
    OP
       257 天前
    @cmdOptionKana 你的意思是对用的数据类型不一致
    Mohanson
        8
    Mohanson  
       257 天前   ❤️ 4
    一句话概括:

    new: 在调用时编译器知道你需要使用多少内存, 例如结构体, 整形或浮点型.
    make: 在调用时编译器不知道你需要使用多少内存, 例如 slice, channel, map ... 这些数据结构占用的内存是运行时才能知晓的
    bruce0
        9
    bruce0  
       257 天前
    @cmdOptionKana new 只能用于结构体 new 不止可以用于结构体, 任何是指针的都可以 用 new

    ```
    m := make(map[int]int)
    m[1] = 1
    a := new(map[int]int)
    a = &m

    fmt.Println(*a)
    ```

    这段代码是没问题的
    cmdOptionKana
        10
    cmdOptionKana  
       257 天前
    @bruce0 可以是可以,但我觉得这类似 JavaScript 的隐性类型转换,有具体规则,但实际使用中提倡不要去研究这些细节,直接采用最佳实践。
    ganbuliao
        11
    ganbuliao  
       257 天前
    对普通的使用者来说只要知道一个是返回引用类型,一个是返回值类型的变量就可以了,要想更深入了解就看代码这两个方法是咋实现的呗。反正我目前还没有要看底层实现的需求。
    zhijiangliu
        12
    zhijiangliu  
       257 天前
    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 用于创建其他数据。
    awanganddong
        13
    awanganddong  
    OP
       257 天前
    @all 谢谢诸位,我理解理解
    tpkeeper
        14
    tpkeeper  
       257 天前
    @mcfog 高手
    guanhui07
        15
    guanhui07  
       257 天前
    make 只能用于 map 、slice 、channel ,new 只能用于结构体。
    tianyou666shen
        16
    tianyou666shen  
       257 天前
    make: 给 slice map channel 分配内存空间,返回这个值.注意这些类型是引用类型变量
    new: 常用来初始化自己定义的结构体,创建对象,返回新建对象的引用

    另外 make([]string,0,5) 可以指定 slice 的长度,容量,
    一开始就能估算出容量可以减少后续一次次扩容的开销
    make(chan,1) 可以创建有缓冲区的 channel
    jakehu
        17
    jakehu  
       257 天前
    make 返回引用对象
    new 返回指针对象
    Joyreece
        18
    Joyreece  
       257 天前 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)
    lizuoqiang
        19
    lizuoqiang  
       256 天前
    ```
    - make 作用于 slice 、map 、channel ,返回值是这些类型的实例
    - new 作用于 array 、struct 等值类型,返回值是分配的地址的指针
    ```
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3308 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 44ms · UTC 01:02 · PVG 09:02 · LAX 17:02 · JFK 20:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.