Go new 和 make 的区别

103 阅读2分钟

Go中,makenew都可以用来初始化变量。那这两个内置函数在使用上的区别是什么呢?

定义

先来看看这两个内置函数的定义:

// 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
​
// 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

go1.17.10 src/builtin/builtin.go

相同点

  • 都可以用来初始化变量
  • 参数都是某个类型,而不是一个具体的值

不同点

从这两个内置函数的定义,我们能直观看出:

  • 参数不同

    • make可以传递多个参数,第一个是类型,第二个开始为int类型的数字
    • new只有一个参数,参数是类型
  • 返回值不同

    • make初始化变量返回值类型
    • new初始化变量返回零值的指针类型
  • 适用类型不同

    • make只用于map、slice和chan类型的初始化

make用于slice、map和chan类型

make用于初始化slice

// 初始化一个长度为0的slice
slice1 := make([]int, 0)
​
// 初始化一个长度为0,容量为10的slice
slice2 := make([]int, 0, 10) // 分配一个大小为10的底层数组并返回一个长度为0,容量为10的slice

make用于初始化slice的时候,有三个可用参数:

  • 第一个:slice的类型,必填参数
  • 第二个:slice的长度,必填参数
  • 第三个:slice的容量,不能比slice的长度小,非必填参数

make用于初始化map

m1 := make(map[string]string)
​
m2 := make(map[string]string, 10)

make用于初始化map的时候,有两个可用参数:

  • 第一个:map的类型,必填参数
  • 第二个:map的起始空间大小,非必填

当map的大小不指定的时候,会默认分配一个较小的起始空间。

make用于初始化chan

// 初始化一个不带缓冲的int类型的channel
c1 := make(chan int)
​
// 初始化一个带缓冲且大小为10的int类型的channel
c2 := make(chan int, 10)

make用于初始化channel的时候,有两个可用参数:

  • 第一个:chan的类型,必填参数
  • 第二个:chan的缓冲大小,非必填

查看原文