Golang: make和new坑(5)

使用 map 的时候,遇到了个坑,来仔细看看 make 以及 new 。

专栏的介绍可以参考 《GotchaGolang专栏》,代码可以看《宝库-Gotcha》

Go语言中new和make是内建的两个函数,主要用来创建分配类型内存。

案例

声明的同时不赋值,也就是没有初始化;基本类型就算了,但是指针类型和引用类型则不行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main
import (
"fmt"
)
func main() {

//基本类型 ok, 声明即定义了
var i int
var s string

var i *int //只声明, 不定义
*i=10
fmt.Println(*i)
}

运行肯定报错了: panic: runtime error: invalid memory address or nil pointer dereference

  • 对于值类型的声明不需要,是因为已经默认帮我们分配好了,默认零值。
  • 对于引用和指针类型,要分配内存,就引出来今天的new和make。

new 内置函数如下:

1
2
3
4
// 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

使用案例如下:

1
2
3
4
5
6
func main() {
var i *int
i=new(int)
//*i=10
fmt.Println(*i) //打印为0,默认会赋值为0值
}

new 返回的具体类型的指针,指向分配类型的内存地址,且类型变量的值为零值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func main() {
u:=new(user) //内部变量全部为 0 值

u.lock.Lock()
u.name = "张三"
u.lock.Unlock()

fmt.Println(u)
}
type user struct {
name string
age int
lock sync.Mutex
}

返回 指针并不一定总是好的,对于引用类型,直接返回它本身就可以了,用 make:

make: 从函数声明中可以看到,返回的还是该类型。

1
func make(t Type, size ...IntegerType) Type

例如:

1
2
3
4
//map1 := map[int]string{}
map1 := make(map[int]string) //也会给与零值
map1[1]="one"
map1[2]="two"

对于 slice, map, chan 一般使用 make 返回这三个引用类型本身,new 返回的是指向类型的指针。

总结

make 还是比较常用的,直接返回引用类型本身;其他时候直接使用段语句 := 在栈上声明更加方便。指针操作,尽量少用。


Merlin 2018.3 make的坑

文章目录
  1. 1. 案例
  2. 2. 总结
|