Go初始化函数make和new有什么区别?

简介: Go初始化函数make和new有什么区别?

1 代码演示下

代码演示:

package main
import "fmt"
func main() {
   testMap()
   fmt.Println("--------")
   testSlice()
   fmt.Println("--------")
   testChannel()
}
func testMap() {
   mmap := make(map[string]int64)
   nmap := new(map[string]int64)
   fmt.Println("&mmap = ", &mmap, "------ mmap = ", mmap)
   fmt.Println("&nmap = ", &nmap, "------ nmap = ", nmap)
   mmap = map[string]int64{"key": 100}
   nmap = &map[string]int64{"key": 100}
   fmt.Println("&mmap = ", &mmap, "------ mmap = ", mmap)
   fmt.Println("&nmap = ", &nmap, "------ nmap = ", nmap)
}
func testSlice() {
   mslice := make([]int, 0, 10)
   mslice2 := make([]int, 0)
   nslice := new([]int)
   fmt.Println("&mslice = ", &mslice, "------ mslice = ", mslice)
   fmt.Println("&mslice2 = ", &mslice2, "------ mslice2 = ", mslice2)
   fmt.Println("&nslice = ", &nslice, "------ nmap = ", nslice)
   mslice = append(mslice, 111)
   mslice2 = append(mslice2, 222)
   *nslice = append(*nslice, 333)
   fmt.Println("&mslice = ", &mslice, "------ mslice = ", mslice)
   fmt.Println("&mslice2 = ", &mslice2, "------ mslice2 = ", mslice2)
   fmt.Println("&nslice = ", &nslice, "------ nmap = ", nslice)
}
func testChannel() {
   mchan := make(chan int, 1)
   mchan2 := make(chan int, 10)
   nchan := new(chan int)
   fmt.Println("&mchan = ", &mchan, "------ mchan = ", mchan)
   fmt.Println("&mchan2 = ", &mchan2, "------ mchan2 = ", mchan2)
   fmt.Println("&nchan = ", &nchan, "------ nchan = ", nchan)
   mchan <- 10
   mchan2 <- 20
   *nchan = make(chan int, 1)
   *nchan <- 30
   fmt.Println("&mchan = ", &mchan, "------ mchan = ", <-mchan)
   fmt.Println("&mchan2 = ", &mchan2, "------ mchan2 = ", <-mchan2)
   fmt.Println("&nchan = ", &nchan, "------ nchan = ", <-*nchan)
}
复制代码

运行结果:

&mmap =  &map[] ------ mmap =  map[]
&nmap =  0xc1200ac020 ------ nmap =  &map[]
&mmap =  &map[key:100] ------ mmap =  map[key:100]
&nmap =  0xc1200ac020 ------ nmap =  &map[key:100]
--------
&mslice =  &[] ------ mslice =  []
&mslice2 =  &[] ------ mslice2 =  []
&nslice =  0xc1200ac040 ------ nmap =  &[]
&mslice =  &[111] ------ mslice =  [111]
&mslice2 =  &[222] ------ mslice2 =  [222]
&nslice =  0xc1200ac040 ------ nmap =  &[333]
--------
&mchan =  0xc1200ac048 ------ mchan =  0xc1200c6000
&mchan2 =  0xc1200ac050 ------ mchan2 =  0xc1200c8000
&nchan =  0xc1200ac058 ------ nchan =  0xc1200ac060
&mchan =  0xc1200ac048 ------ mchan =  10
&mchan2 =  0xc1200ac050 ------ mchan2 =  20
&nchan =  0xc1200ac058 ------ nchan =  30
复制代码

2 翻源码深入了解下

源码:

// The make built-in function allocates and initializes an object of type
// slice, map, or chan (only). Like new, the first argument is a type, not a
// value. Unlike new, make's return type is the same as the type of its
// argument, not a pointer to it. The specification of the result depends on
// the type:
// Slice: The size specifies the length. The capacity of the slice is
// equal to its length. A second integer argument may be provided to
// specify a different capacity; it must be no smaller than the
// length. For example, make([]int, 0, 10) allocates an underlying array
// of size 10 and returns a slice of length 0 and capacity 10 that is
// backed by this underlying array.
// Map: An empty map is allocated with enough space to hold the
// specified number of elements. The size may be omitted, in which case
// a small starting size is allocated.
// Channel: The channel's buffer is initialized with the specified
// buffer capacity. If zero, or the size is omitted, the channel is
// unbuffered.
func make(t Type, size ...IntegerType) Type
// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
func new(Type) *Type
复制代码

简单翻译下:

//make内置函数分配并初始化一个类型对象切片、映射或chan(仅这三个)。像new一样,第一个参数是一个类型,而不是value。与new不同,make的返回类型与他的参数类型相同,而不是指向它的指针。结果的规格取决于类型:
//- Slice:大小指定长度。切片的容量为等于它的长度。可以提供第二个整数参数指定不同的容量;它必须不小于长度。例如,make([]int, 0,10)分配一个底层数组的大小为10,返回长度为0,容量为10的切片由此基础数组支持。
//- Map:为空映射分配足够的空间来容纳指定的元素数。在这种情况下,可以省略字号分配一个小的起始大小。
//- Channel:通道的缓冲区用指定的参数初始化缓冲能力。如果为零,或者省略了大小,则通道为无缓冲的。
func make(t Type, size ...IntegerType) Type
//new的内置函数分配内存。第一个参数是一个类型,不是一个value,返回的值是一个指向new的指针分配该类型的零值。
func new(Type) *Type
复制代码

3 总结下

Go语言中的 new 和 make 主要区别如下:

  • make 只能用来分配及初始化类型为 slice、map、chan 的数据。new 可以分配任意类型的数据;
  • new 分配返回的是指针,即类型 *Type。make 返回引用,即 Type;
  • new 分配的空间被清零。make 分配空间后,会进行初始化;

最后,简单总结一下Go语言中 make 和 new 关键字的实现原理,make 关键字的主要作用是创建 slice、map 和 Channel 等内置的数据结构,而 new 的主要作用是为类型申请一片内存空间,并返回指向这片内存的指针。


相关文章
|
1月前
|
存储 Rust Go
Go nil 空结构体 空接口有什么区别?
本文介绍了Go语言中的`nil`、空结构体和空接口的区别。`nil`是预定义的零值变量,适用于指针、管道等类型;空结构体大小为0,多个空结构体实例指向同一地址;空接口由`_type`和`data`字段组成,仅当两者均为`nil`时,空接口才为`nil`。
Go nil 空结构体 空接口有什么区别?
|
1月前
|
JSON 安全 网络协议
go语言使用内置函数和标准库
【10月更文挑战第18天】
16 3
|
3月前
|
Go
go函数
go函数
34 10
|
3月前
|
编译器 Go C++
Go to Learn Go之函数
Go to Learn Go之函数
29 0
|
3月前
|
编译器 Go 索引
Go数组、多维数组和切片(动态数组),及常用函数len(),cap(),copy(),append()在切片中的使用
本文介绍了Go语言中数组、多维数组和切片(动态数组)的基本概念和操作,包括数组的定义、初始化、访问,多维数组的定义和访问,以及切片的创建、使用和扩容。同时,还讲解了切片中常用的函数len()、cap()、copy()和append()的使用方法。
|
4月前
|
Unix 编译器 Go
|
4月前
|
设计模式 Java 数据库连接
|
4月前
|
Go 开发者
|
Go
Golang中make与new有何区别?
本文主要给大家介绍了Go语言中函数`new`与`make`的使用和区别,关于Go语言中`new`和`make`是内建的两个函数,主要用来创建分配类型内存。在我们定义生成变量的时候,可能会觉得有点迷惑,其实他们的规则很简单,下面我们就通过一些示例说明他们的区别和使用。
107 0
|
7天前
|
存储 Go 索引
go语言使用for循环遍历
go语言使用for循环遍历
21 7