Golang 中 make 和 new 的区别?
共同点:都会分配内存空间(堆上)
不同点:
① 作用变量不同,new 可以为任意类型分配内存;但是 make 只能给,切片、map、chan分配内存。
② 返回类型不同,new 返回的是指向变量的指针;make 返回的是上边三种变量类型本身。
③ new 对分配的内存清零;make会根据你的设定进行初始化,比如在设置长度、容量的时候。
简单说明
new只能用来分配内存。
make只能用于slice、map以及channel引用类型的初始化。
new 函数
1 分配内存
2 设置零值
3 返回指针(重要)
package make
import "fmt"
type Student struct {
name string
age int
}
func main() {
// new 一个内建类型
num := new(int)
fmt.Println(*num) //打印零值:0
// new 一个自定义类型
s := new(Student)
s.name = "wangbm"
fmt.Println(s) // 打印零值:&{wangbm 0}
}
make 函数
1、内建函数 make 用来为 slice,map 或 chan 类型。
(注意:也只能用在这三种类型上)分配内存和初始化一个对象。
2、make 返回类型的本身而不是指针,而返回值也依赖于具体传入的类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。
注意,因为这三种类型是引用类型,所以必须得初始化(size 和 cap),但不是置为零值,这个和 new是不一样的。
举几个例子
//切片
a := make([]int, 2, 10)
// 字典
b := make(map[string]int)
// 通道
c := make(chan int, 10)
总结
new:为所有的类型分配内存,并初始化为零值,返回指针。
make:只能为 slice,map,chan 分配内存,并初始化,返回的是类型。
另外,目前来看 new 函数并不常用,大家更喜欢使用短语句声明的方式。
a := new(int)
*a = 1
// 等价于
a := 1
但是 make 就不一样了,它的地位无可替代,在使用slice、map以及channel的时候,还是要使用make进行初始化,然后才可以对他们进行操作。
package main
import "fmt"
func main() {
var slice1 []int = []int{1, 2, 3, 4, 5}
fmt.Println(slice1)
}
new() 函数创建切片指针示例
package main
import "fmt"
func main() {
// 使用 new() 创建一个指向切片的指针
var slicePtr *[]int
slicePtr = new([]int)
// 使用 make() 创建一个实际的切片,并将指针赋值给它
*slicePtr = make([]int, 5)
fmt.Println(*slicePtr) // 打印切片
}
[0 0 0 0 0]
new() 函数创建切片指针后,切片本身还没有被创建,它的长度为零,不能直接赋值。
你需要先使用 make() 函数创建切片,然后再赋值。
以下是修正后的代码:
package main
import "fmt"
func main() {
// 使用 new() 创建一个指向切片的指针
var slicePtr *[]int
slicePtr = new([]int)
// 使用 make() 创建一个实际的切片,并将指针赋值给它
*slicePtr = make([]int, 5)
// 给切片赋值
(*slicePtr)[0] = 1
(*slicePtr)[1] = 2
(*slicePtr)[2] = 3
(*slicePtr)[3] = 4
(*slicePtr)[4] = 5
fmt.Println(*slicePtr) // 打印切片
}
这将正常工作并输出 [1 2 3 4 5]。
在这个修正后的代码中,我们首先使用 new() 函数创建了一个指向切片的指针,
然后使用 make() 函数创建了一个包含5个整数的切片,并将指针赋值给它。
然后,我们可以使用索引逐个为切片赋值,并最终打印整个切片。