go中new()与make()区别
Posted -wenli
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go中new()与make()区别相关的知识,希望对你有一定的参考价值。
一、new
函数原型:func new(Type) *Type
函数作用:用来分配内存,只有是一个参数,参数为类型,它的返回值是一个指向新分配类型的指针,并且内存置为零。
package main import "fmt" func main() { test1 := new(int)//创建int类型的指针,用来存储int类型变量的地址 var a int = 2 test1 = &a fmt.Printf("%d ",*test1) test2 := new(string)//创建string类型的指针,用来存储string类型变量的地址 var b string = "hello" test2 = &b fmt.Printf("%s ",*test2) }
new的使用场景
new用来初始化结构体,返回结构体类型指针。
package main type User struct { user string password string } func main() { //第一种方式 u1 := new(User)//创建User类型的指针 u1.user = "root" u1.password = "passwd" //第二种方式 u2 := &User{} u2.user = "root" u2.password = "passwd" //第一种方法等效于第二种方式 }
二、make
函数原型:func make(Type, size IntegerType) Type
函数功能:内建函数 make 用来为 slice,map 或 chan 类型分配内存和初始化一个对象(注意:只能用在这三种类型上)。
跟 new 相同的是,第一个参数也是一个类型,跟 new 不同的是,make 返回类型的引用而不是指针,而返回值也依赖于具体传入的类型。
通过下表再来看 make 的具体应用:
Call | Type T | Result |
make(T, n) | slice | slice of type T with length n and capacity n |
make(T, n, m) | slice | slice of type T with length n and capacity m |
make(T) | map | map of type T |
make(T, n) | map | map of type T with initial space for n elements |
make(T) | channel | unbuffered channel of type T |
make(T, n) | channel | buffered channel of type T, buffer |
Slice:
如果传入两个参数,第二个参数 size 指定了它的长度,它的容量和长度相同,比如make([]int,5)。
如果传入三个参数,第三个参数来指定不同的容量值,但必须不能比长度值小,比如 make([]int, 0, 10)。
切片拥有 长度 和 容量。
切片的长度就是它所包含的元素个数。
切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。
切片 s
的长度和容量可通过表达式 len(s)
和 cap(s)
来获取。
- 容量的用处:在与当你用 appen d扩展长度时,如果新的长度小于容量,不会更换底层数组,否则,go 会新申请一个底层数组,拷贝这边的值过去,把原来的数组丢掉。也就是说,容量的用途是在数据拷贝和内存申请的消耗与内存占用之间提供一个权衡,也表示切片的容量随着长度的变化而变化。
- 长度的用途:是为了帮助你限制切片可用成员的数量,提供边界查询的。所以用 make 申请好空间后,需要注意不要越界【越 len 】。
//创建一个初始元素个数为5的数组切片,元素初始值为0 a := make([]int, 5) // len(a)=5 //创建一个初始元素个数为5的数组切片,元素初始值为0,容量为10 b := make([]int, 5, 10) // len(b)=5, cap(b)=10
Map: 根据 size 大小来初始化分配内存,不过分配后的 map 长度为 0,如果 size 被忽略了,那么会在初始化分配内存时分配一个小尺寸的内存。
Channel: 管道缓冲区依据缓冲区容量被初始化。如果容量为 0 或者忽略容量,管道是没有缓冲区的。
以上是关于go中new()与make()区别的主要内容,如果未能解决你的问题,请参考以下文章