发布于2026-07-12 阅读(0)
扫一扫,手机访问
先说一个核心判断:make 和 new 可不是随便换着用的。用错了,轻则 panic,重则运行时 nil 指针解引用。这根本不是风格差异,而是 Go 类型系统给你划下的硬杠杠。
简单来说,make 是专门给 slice、map、chan 这三个“亲儿子”用的。其他任何类型,比如 struct、[]int 的指针、*map[string]int,你传给 make,编译器直接翻脸,编译失败。
make([]int, 5) ✅ 返回一个长度为 5、元素全为 0 的切片值,直接可用make(map[string]int) ✅ 返回一个可直接 m["k"] = 1 赋值的 map 值make(chan int, 10) ✅ 返回带缓冲区的 channel 值make(struct{X int}) ❌ 编译错误:cannot make type struct { X int }make(*[]int) ❌ 编译错误:cannot make type *[]int这是两者最本质的区别。new(T) 永远返回 *T,一个指向 T 类型零值的指针;而 make(T, ...),只认那三种类型,返回的是 T 类型的值(不是指针),并且已经初始化好,拿过来就能用。
p := new(int) → p 是 *int,*p == 0s := make([]int, 3) → s 是 []int,len(s) == 3,可直接 s[0] = 1m := new(map[string]int) ❌ 不合法:虽然语法上 new 允许,但它返回的是 *map[string]int,一个指向 nil map 的指针。解引用后 *m 仍然是 nil,后续 (*m)["k"] = 1 必然 panic。很多新手会写 var m = new(map[string]int) 或 m := new(map[string]int),看着合法,但实际拿到的只是一个指向 nil map 的指针。结果就是,解引用后,你面对的还是 nil,啥也干不了。
m := new(map[string]int) → m 类型是 *map[string]int,*m == nil(*m)["x"] = 1 → panic: assignment to entry in nil mapm := make(map[string]int)(要值),要么 m := &map[string]int{}(先 make 再取地址,实际很少用)s := new([]int) 得到的是 *[]int,*s == nil,对 *s 调用 append 也会 panic。对于结构体,make 肯定不行,new 也不是最佳选择。优先用字面量;需要指针时,&MyStruct{} 比 new(MyStruct) 更直观,而且还能顺手设置初始字段值。
s := MyStruct{Name: "a"} → 值类型,栈上分配可达s := &MyStruct{Name: "a"} → 指针,等价于 new(MyStruct) + 字段赋值,但写法更清晰new(MyStruct) → 所有字段都是零值,无法指定初始值,语义弱了一截make(MyStruct) → 编译报错:cannot make type MyStruct一个容易被忽略的细节是:你写的变量是否「需要被外部修改」,或者内部是否「含有需要初始化的引用字段」——到这时候,通常得自己写 NewXXX() 函数,而不是依赖 new 或 make 来解决。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8