[Golang 学习1]Go语言中函数new与make的使用和区别

Go语言中函数new与make的使用和区别

简介

Go语言中有两个生成函数new与make,容易混淆。故总结一下使用和区别。

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

问题的引出:变量声明

var i int
var s string

变量的声明我们可以通过var关键字,然后就可以在程序中使用。
当我们不指定变量的默认值时,这些变量的默认值是他们的零值,比如:int类型的零值是0,string类型的零值是"",引用类型(数组、切片、指针等)的零值是nil。

对于例子中的两种类型的声明,我们可以直接使用,对其进行赋值输出。但是如果我们换成引用类型呢?

package main
import (
 "fmt"
)
func main() {
 var i *int
 *i=10
 fmt.Println(*i)
}

运行的时候会painc,如下:

panic: runtime error: invalid memory address or nil pointer dereference./ *无效的内存地址或无指针取消引用

可以看出,对于引用类型的变量,我们不光要声明它,还要为它分配内容空间。(Golang里引用类型定义即为“内存区域”)。

要分配内存,就引出来今天的new和make。

new

new 可以用来初始化泛型,並且返回内存地址。所以通常我們会用指针变量来接 new 后的type。

特別要注意的是,new 会自动用 zeroed value 来初始化type,也就是字串会是"",number 会是 0,channel, func, map, slice 等等则会是 nil。
因为这个特性,如果我们对 map 做以下的操作的話,会出现 panic: assignment to entry in nil map:

func main() {
    people := new(map[string]string)
    p := *people
    p["name"] = "Kalan" // panic: assignment to entry in nil map
}

因为初始化的map会是nil map,不像其他的primitive type一样有预设值。
如果用struct做初始化,也可以直接用&代表指向的位址,下面两个写法效果是一样的:

type Person struct {
  Name string
  Age  int
}

func main() {
    p := &Person{}
    p := new(Person)
}

好处是上面的Person也可以根据自己想要传入的值额外再做设定,但new则是全部的field都会直接塞zeroed value

make

makenew不同,是用来初始化一些特别的型别,像是channel,map,slice等等。另外特别要注意的是make并不会回传指针,如果要拿到指针,就要考虑用像是new的方式来初始化型别。

func main() {
    receiver := make(chan string) // 初始化 channel,但不回傳指標
    person := make(map[string]string)
    people := make([]string, 100) // 初始化長度為 100 的字串陣列
}

总结

二者都是内存的分配(堆上),但是make只用于slice、map以及channel的初始化(非零值);而new用于类型的内存分配,并且内存置为零。所以在我们编写程序的时候,就可以根据自己的需要很好的选择了。

make返回的还是这三个引用类型本身,更常用;而new返回的是指向类型的指针,实际工作中不太常用。

你可能感兴趣的:(golang学习)