go中make和new的区别

go中make和new的区别

在golang中,make和new都是用来初始化的语句

New

我们可以用下面的语法声明一个变量

func main() {
	a := new(int)
	fmt.Println(reflect.TypeOf(a))
}

输出
*int

可以看到,用new来声明一个T型数据类型,返回的是T*变量

我们来看一下a所占的字节大小,以及a所指向的地址的字节大小

func main() {
	a := new(int)
	fmt.Println(unsafe.Sizeof(a))
	fmt.Println(unsafe.Sizeof(*a))
	fmt.Println(a)
	fmt.Println(*a)
}

输出:
8
8
0xc00000a0d8
0

可以看出,通过new初始化,go会返回一块以及初始化的内存块来,并且为其赋零值,在该例子中,我们通过输出unsafe.Size0f(*a)可以确认a所指向的地址被初始化了内存空间,并赋予了初值。

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

注释中提到,会对该类型赋零值。

make

值得一提的是,在go中,make只用于声明映射、切片和信道,所以下面的语句是错误的

	a := make(int32)// wrong
	fmt.Println(a)

我们通过make一个切片,并用同样的逻辑来测试make返回的类型是什么,是否为变量声明内存空间,又是否会赋初值

func main() {
	a := make([]int, 0)
	fmt.Println(reflect.TypeOf(a))
}

输出:
[]int

可以看到,与new不同的是,make直接返回了切片类型,而不是类型的指针,继续用下面代码验证make的预分配机制

func main() {
	a := make([]int64, 0)
	fmt.Println(reflect.TypeOf(a))
	fmt.Println(unsafe.Sizeof(a))
	fmt.Println(a)
}
输出:
[]int
24
[]

我们可以看到,make同样为变量分配了内存空间,至于内存空间大小24个自己包括了什么,大家可以去分析切片的源码,这里不多赘述,因为不同的数据类型,分配的大小并不一致,比如下面的代码

func main() {
	a := make([]int64, 0)
	fmt.Println(reflect.TypeOf(a))
	fmt.Println(unsafe.Sizeof(a))
}
输出:
chan int
8

总结

new返回T*类型,make返回T类型

make只能用于声明引用类型,比如切片 chan ,像一些基础数据类型或者自己实现的结构体只能使用new

无论new还是make,go都会申请内存空间并赋予0值,具体的内存空间大小取决与数据结构

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值