new
new 可以用来初始化泛型,并且返回储存位址。所以通常我们会用指标变数来接 new 过后的型别。特别要注意的是,new 会自动用 zeroed value 来初始化型别,也就是字串会是"",number 会是 0,channel, func, map, slice 等等则会是 nil。
map 示例
func main() {
people := new(map[string]string)
p := *people
p["name"] = "Kalan" // panic: assignment to entry in nil map
}
silce 示例
func main() {
var a *[]int
fmt.Printf("a: %p %#v \n", &a, a) //a: 0xc042004028 (*[]int)(nil)
av := new([]int)
fmt.Printf("av: %p %#v \n", &av, av) //av: 0xc000074018 &[]int(nil)
(*av)[0] = 8
fmt.Printf("av: %p %#v \n", &av, av) //panic: runtime error: index out of range
}
下面这段代码能否通过编译,不能的话原因是什么
func main() {
list := new([]int)
list = append(list, 1)
fmt.Println(list)
}
append函数的定义如下,不能接收指针类型。
func main() {
list := new([]int)
*list = append(*list, 1)
fmt.Println(*list)
}
channel示例
func main() {
cv := new(chan string)
fmt.Printf("cv: %p %#v \n", &cv, cv) //cv: 0xc000074018 (*chan string)(0xc000074020)
cv <- "good" //会报 invalid operation: cv <- "good" (send to non-chan type *chan string)
}
因为初始化的 map 会是 nil map,nil是不能直接赋值的。并且不能用new分配内存。无法直接赋值
make
make 是 Golang 的内建函数,仅用于分配和初始化 slice、map 以及 channel 类型的对象,三种类型都是结构。返回值为类型,而不是指针。
func main() {
receiver := make(chan string) // 初始化 channel,但不回传指标
person := make(map[string]string)
people := make([]string, 100) // 初始化长度为 100 的字串阵列
}
new 和 make的区别
- make和new都是golang用来分配内存的內建函数,且在堆上分配内存,make 即分配内存,也初始化内存。new只是将内存清零,并没有初始化内存。
- make返回的还是引用类型本身;而new返回的是指向类型的指针。
- make只能用来分配及初始化类型为slice,map,channel的数据;new可以分配任意类型的数据。