欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

golang中,new和make的区别

程序员文章站 2022-03-21 17:45:38
在golang中,make和new都是分配内存的,但是它们之间还是有些区别的,只有理解了它们之间的不同,才能在合适的场合使用。 简单来说,new只是分配内存,不初始化内存; 而make即分配又初始化内存。所谓的初始化就是给类型赋初值,比如字符为空,整型为0, 逻辑值为false等。 new 先看下n ......

在golang中,make和new都是分配内存的,但是它们之间还是有些区别的,只有理解了它们之间的不同,才能在合适的场合使用。

简单来说,new只是分配内存,不初始化内存; 而make即分配又初始化内存。所谓的初始化就是给类型赋初值,比如字符为空,整型为0, 逻辑值为false等。

new

先看下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

可以看出,它的参数是一个类型,返回值为指向该类型内存地址的指针,同时会把分配的内存置为零,也就是类型的零值, 即字符为空,整型为0, 逻辑值为false

看几个new的示例

   type p struct{
        name string
        age int
    }
    var a *[2]int
    var s *string
    var b *bool
    var i *int
    var ps *p

    a = new([2]int)
    s = new(string)
    b = new(bool)
    i = new(int)
    ps = new(p) //结构

    fmt.println(a, " ", *a)
    fmt.println(s,  " ",*s)
    fmt.println(b,  " ",*b)
    fmt.println(i,  " ",*i)
    fmt.println(ps, " ", *ps)

输出结果如下

&[0 0]   [0 0]
0xc00000e1e0   
0xc00001a07a   false
0xc00001a090   0
&{ 0}   { 0}

上面示例是基本的类型,再看下slice, map,chan这些用new咋操作

    map操作
    var mp *map[string]string
    mp = new(map[string]string)
    //*mp = make(map[string]string)  //这行注掉会panic "panic: assignment to entry in nil map""
    (*mp)["name"] = "lc"
    fmt.println((*mp)["name"])
    
    slice操作
    var ms *[]string
    ms = new([]string)
    //*ms = make([]string,5) //这行注掉会pance "panic: runtime error: index out of range"
    (*ms)[0] = "lc"
    fmt.println((*ms)[0])
    

上面可以看出,silce、map、channel等类型属于引用类型,引用类型初始化为nil,nil是不能直接赋值的,也不能用new分配内存,还需要使用make来分配。

make

看下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. the specification of the result depends on
// the type:
//  slice: the size specifies the length. the capacity of the slice is
//  equal to its length. a second integer argument may be provided to
//  specify a different capacity; it must be no smaller than the
//  length. for example, make([]int, 0, 10) allocates an underlying array
//  of size 10 and returns a slice of length 0 and capacity 10 that is
//  backed by this underlying array.
//  map: an empty map is allocated with enough space to hold the
//  specified number of elements. the size may be omitted, in which case
//  a small starting size is allocated.
//  channel: the channel's buffer is initialized with the specified
//  buffer capacity. if zero, or the size is omitted, the channel is
//  unbuffered.
func make(t type, size ...integertype) type

可以看出,它返回的就是类型本身,而不是指针类型,因为make只能给slice,map,channel等初始化内存,它们返回的就是引用类型,那么就没必要返回指针了

看下make的一些示例

    mm :=make(map[string]string)
    mm["name"] = "lc"
    fmt.println(mm["name"])

    mss :=make([]int,2)
    mss[0] = 100
    fmt.println(mss[0])

    ch :=make(chan int,1)
    ch <-100

    fmt.println(<-ch)

小结

make 仅用来分配及初始化类型为 slice、map、chan 的数据。new 可分配任意类型的数据.
new 分配返回的是指针,即类型 *type。make 返回引用,即 type.
new 分配的空间被清零, make 分配空间后,会进行初始化.