makenew都用于分配内存,不同的是,make只能用于 slicemapchannel 这三种数据类型的内存创建

那么他们还有什么不同吗,且听我娓娓道来

分配内存

要说到这两个的区别,我们还得从分配内存讲起。

众所周知,在Golang中,如果我们声明了一个指针,而没有为其分配内存空间,那么是无法修改其值的,例如如下代码:

package main

import "fmt"

func main() {
    var p *string
    *p = "hello"
    fmt.Println(*p)
}

//输出:
//panic: runtime error: invalid memory address or nil pointer dereference
//[signal 0xc0000005 code=0x0 addr=0x0 pc=0xa2c51a]

因为,当一个指针没有分配内存时,其零值为 nil,因此,使用 new为其分配内存空间,即可使用该指针:

package main

import "fmt"

func main() {
    var p *string
    p = new(string)
    *p = "hello"
    fmt.Println(*p)
}

//输出:
//hello

对于 newmake,他们做的都是一件事情,那就是分配内存

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

new是内置函数分配内存。参数是类型,而不是值,返回的值是指向该类型新分配的零值的指针。

使用

type Test struct {
    i int
}

//...

test1 := new(Test)
test2 := &Test{}

其中,new(Test),与 &Test{}是等价的,都是分配内存空间并返回一个指针,正因为如此,new在实际使用中用的比较少。

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内置函数分配并初始化一个仅限于slicemapchan类型的对象
  • new相同的是:第一个参数是类型,而不是具体值
  • new不同的是:make的返回类型与其参数相同的类型,而不是指向它的指针。

使用

//slice
//创建一个容量为0,长度为0的slice
s1 := make([]int,0)
//创建一个容量为10,长度为0的slice
s2 := make([]int,0,10)

//map
//创建一个没有指定容量的map
m1 := make(map[string]string)
//创建一个指定容量为10的map
m2 := make(map[string]string,10)

//channal
//创建一个缓冲容量为100的channel
c1 := make(chan int,100)
//创建一个无缓冲channel
c2 := make(chan int)

总结一下

  • make 只能用来分配及初始化类型为 slice、map、chan 的数据。new 可以分配任意类型的数据;
  • new 分配返回的是指针,即类型 *Type。make 返回引用,即 Type;
  • new 分配的空间被清零。make 分配空间后,会进行初始化;
最后修改:2022 年 01 月 11 日
如果觉得我的文章对你有用,请随意赞赏