浅谈go语言中的make和new的区别

113 阅读2分钟

前言

本文是探讨的是"go语言中的make和new的区别"

此文章是个人学习归纳的心得, 为掘金首发 , 如有不对, 还望指正, 感谢!

使用范围不同

make内置函数仅用于slice(切片),map(映射),chan(管道)类型的对象的分配并初始化

package main

import "fmt"

func main() {

   // 创建
   sliceDemo := make([]string, 6, 6)
   mapDemo := make(map[int]string)
   mapDemo2 := make(map[int]string, 1)
   chanDemo := make(chan int, 10)

   // 进行打印
   mapDemo2[1] = "1"
   mapDemo2[2] = "2"
   fmt.Printf("sliceDemo:%v %[1]T len:%[2]v cap:%[3]v \n", sliceDemo, len(sliceDemo), cap(sliceDemo))
   fmt.Printf("mapDemo:%v %[1]T len:%[2]v \n", mapDemo, len(mapDemo))
   fmt.Printf("mapDemo2:%v %[1]T len:%[2]v  \n", mapDemo2, len(mapDemo2))
   fmt.Printf("chanDemo:%v %[1]T len:%[2]v cap:%[3]v \n", chanDemo, len(chanDemo), cap(chanDemo))

}

输出结果:

image.png

new可以用于任何类型的创建,不像make不能用于结构体的创建,new就可以

package main

import "fmt"

func main() {
 
   // 定义学生结构体
   type stu struct {
      name string
      age  int
   }

   // new一个
   y3 := new(stu)
  
   fmt.Printf("y3 :%v %[1]T \n", y3)
}

image.png

返回值不同

make的返回类型与其参数的类型相同,而new返回的是指向传入类型的指针。

package main

import "fmt"

func main() {

   type stu struct {
      name string
      age  int
   }


   y1 := stu{"yzc", 20}
   y2 := &stu{"yzc", 20}
   y3 := new(stu)

   fmt.Printf("y1 :%v %[1]T \n", y1)
   fmt.Printf("y2 :%v %[1]T \n", y2)
   fmt.Printf("y3 :%v %[1]T \n", y3)
}

image.png

我们深入分析 , 可以发现发现make函数返回的是一个已初始化的非零值对象。对于slice和map,make函数还会分配内存并返回一个引用,而对于channel,make函数会返回一个引用(channel类型的值本身就是引用类型)。

slice := make([]int, 0, 10) // 创建一个长度为0,容量为10的切片
m := make(map[string]int) // 创建一个空的map
ch := make(chan int, 10) // 创建一个带有缓冲区的channel

而new函数只分配内存,并没有进行初始化操作。

p := new(int) // 创建一个int类型的零值对象,并返回指向该对象的指针