zoukankan      html  css  js  c++  java
  • Go语言中new()和 make()的区别详解

    概述

    Go 语言中的 new 和 make 一直是新手比较容易混淆的东西,咋一看很相似。不过解释两者之间的不同也非常容易。

    new 的主要特性

    首先 new 是内建函数,你可以从 http://golang.org/pkg/builtin/#new 这儿看到它,它的定义也很简单:

    复制代码代码如下:

    func new(Type) *Type

    官方文档对于它的描述是:

    复制代码代码如下:

    内建函数 new 用来分配内存,它的第一个参数是一个类型,不是一个值,它的返回值是一个指向新分配类型零值的指针

    根据这段描述,我们可以自己实现一个类似 new 的功能:

    复制代码代码如下:

    func newInt() *int {
      var i int
      return &i
    }

    someInt := newInt()

    我们这个函数的功能跟 someInt := new(int) 一模一样。所以在我们自己定义 new 开头的函数时,出于约定也应该返回类型的指针。

    make 的主要特性

    make 也是内建函数,你可以从 http://golang.org/pkg/builtin/#make 这儿看到它,它的定义比 new 多了一个参数,返回值也不同:

    复制代码代码如下:

    func make(Type, size IntegerType) Type

    官方文档对于它的描述是:

    内建函数 make 用来为 slice,map 或 chan 类型分配内存和初始化一个对象(注意:只能用在这三种类型上),跟 new 类似,第一个参数也是一个类型而不是一个值,跟 new 不同的是,make 返回类型的引用而不是指针,而返回值也依赖于具体传入的类型,具体说明如下:

    复制代码代码如下:

    Slice: 第二个参数 size 指定了它的长度,它的容量和长度相同。
    你可以传入第三个参数来指定不同的容量值,但必须不能比长度值小。
    比如 make([]int, 0, 10)

    Map: 根据 size 大小来初始化分配内存,不过分配后的 map 长度为 0,如果 size 被忽略了,那么会在初始化分配内存时分配一个小尺寸的内存

    Channel: 管道缓冲区依据缓冲区容量被初始化。如果容量为 0 或者忽略容量,管道是没有缓冲区的

    总结

    new 的作用是初始化一个指向类型的指针(*T),make 的作用是为 slice,map 或 chan 初始化并返回引用(T)。

    小结

    new(T) 返回 T 的指针 *T 并指向 T 的零值。

    make(T) 返回的初始化的 T,只能用于 slice,map,channel。

    我们的例子中,如果没有*i=10,那么打印的就是0。这里体现不出来new函数这种内存置为零的好处,我们再看一个例子。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    func main() {
     u:=new(user)
     u.lock.Lock()
     u.name = "张三"
     u.lock.Unlock()
     fmt.Println(u)
    }
    type user struct {
     lock sync.Mutex
     name string
     age int
    }

    示例中的user类型中的lock字段我不用初始化,直接可以拿来用,不会有无效内存引用异常,因为它已经被零值了。

    这就是new,它返回的永远是类型的指针,指向分配类型的内存地址。

    make

    make也是用于内存分配的,但是和new不同,它只用于chan、map以及切片的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。

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

    1
    func make(t Type, size ...IntegerType) Type

    从函数声明中可以看到,返回的还是该类型

  • 相关阅读:
    wordpress升级需设置ftp的解决方法
    用命令创建MySQL数据库
    MySQL创建用户与授权
    MySQL基本命令和常用数据库对象
    转换说明符和转换说明修饰符
    html-webpack-plugin
    数据库-之MySQL的dos命令
    浅谈Java拆箱、装箱
    Java基础问题10问
    Java单例类
  • 原文地址:https://www.cnblogs.com/ExMan/p/14607690.html
Copyright © 2011-2022 走看看