开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4天,点击查看活动详情
前言
Go的指针类型,必须要先做初始化(即分配内存地址),然后才能正确的做写操作。初始化可以使用new或make,这两个内置函数来完成,但两者之间有所区别,需要注意。
先说结论
区别点:
- 主要作用不同:
new只分配内存,获取指向某个类型的指针 ;make主要作用是初始化内置的数据结构,也就是 slice、map 和 channel 的初始化 - 函数返回值不同:
new返回对应类型的指针;make返回对应类型的本身 - 作用范围不同:
new可作用于任何类型;make只作用于slice、map、channel
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 函数只接受一个参数,这个参数是一个类型,并且返回一个指向该类型内存地址的指针。同时 new 函数会把分配的内存置为零,也就是类型的零值。
使用例子:
var num *int
num = new(int) //使用new初始化,分配内存地址
*num = 100
fmt.Println(num) //0xc00001a098
如果未使用new进行初始化,则会panic:
panic: runtime error: invalid memory address or nil pointer dereference
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
解释说明:参数t只用于 slice、map 以及 chan 的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。
另外,在编译期间的类型检查阶段,Go语言其实就将代表 make 关键字的 OMAKE 节点根据参数类型的不同转换成了 OMAKESLICE、OMAKEMAP 和 OMAKECHAN三种不同类型的节点,这些节点最终也会调用不同的运行时函数来初始化数据结构。
使用例子:
var m map[string]string
m = make(map[string]string) //使用make初始化,分配内存地址
m["name"] = "zhangsan"
fmt.Println(m, fmt.Sprintf("%p", m)) //map[name:zhangsan] 0xc000100030
如果未使用make进行初始化,则会panic:
panic: assignment to entry in nil map
总结
可使用new或make对指针类型进行初始化。new可作用于任何类型,并返回对应类型的指针;make只作用于slice、map和channel,并返回对应类型的本身。
如果本文对你有帮助,欢迎点赞收藏加关注,如果本文有错误的地方,欢迎指出!