make
和 new
都用于分配内存,不同的是,make
只能用于 slice
、map
、channel
这三种数据类型的内存创建
那么他们还有什么不同吗,且听我娓娓道来
分配内存
要说到这两个的区别,我们还得从分配内存讲起。
众所周知,在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
对于 new
和 make
,他们做的都是一件事情,那就是分配内存
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
内置函数分配并初始化一个仅限于slice
,map
或chan
类型的对象- 与
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 分配空间后,会进行初始化;