在golang中,make和new都是分配内存的,但是它们之间还是有些区别的,只有理解了它们之间的不同,才能在合适的场合使用。

简单来说,new只是分配内存,不初始化内存; 而make即分配又初始化内存。所谓的初始化就是给类型赋初值,比如字符为空,整型为0, 逻辑值为false等。

new

先看下new函数的定义

// 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

可以看出,它的参数是一个类型,返回值为指向该类型内存地址的指针,同时会把分配的内存置为零,也就是类型的零值, 即字符为空,整型为0, 逻辑值为false

看几个new的示例

   type P struct{
Name string
Age int
}
var a *[2]int
var s *string
var b *bool
var i *int
var ps *P a = new([2]int)
s = new(string)
b = new(bool)
i = new(int)
ps = new(P) //结构 fmt.Println(a, " ", *a)
fmt.Println(s, " ",*s)
fmt.Println(b, " ",*b)
fmt.Println(i, " ",*i)
fmt.Println(ps, " ", *ps)

输出结果如下

&[0 0]   [0 0]
0xc00000e1e0
0xc00001a07a false
0xc00001a090 0
&{ 0} { 0}

上面示例是基本的类型,再看下slice, map,chan这些用new咋操作

    map操作
var mp *map[string]string
mp = new(map[string]string)
//*mp = make(map[string]string) //这行注掉会panic "panic: assignment to entry in nil map""
(*mp)["name"] = "lc"
fmt.Println((*mp)["name"]) slice操作
var ms *[]string
ms = new([]string)
//*ms = make([]string,5) //这行注掉会pance "panic: runtime error: index out of range"
(*ms)[0] = "lc"
fmt.Println((*ms)[0])

上面可以看出,silce、map、channel等类型属于引用类型,引用类型初始化为nil,nil是不能直接赋值的,也不能用new分配内存,还需要使用make来分配。

make

看下make的函数声明

/ 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

可以看出,它返回的就是类型本身,而不是指针类型,因为make只能给slice,map,channel等初始化内存,它们返回的就是引用类型,那么就没必要返回指针了

看下make的一些示例

    mm :=make(map[string]string)
mm["name"] = "lc"
fmt.Println(mm["name"]) mss :=make([]int,2)
mss[0] = 100
fmt.Println(mss[0]) ch :=make(chan int,1)
ch <-100 fmt.Println(<-ch)

小结

make 仅用来分配及初始化类型为 slice、map、chan 的数据。new 可分配任意类型的数据.

new 分配返回的是指针,即类型 *Type。make 返回引用,即 Type.

new 分配的空间被清零, make 分配空间后,会进行初始化.

golang中,new和make的区别的更多相关文章

  1. 【GoLang】GoLang 中 make 与 new的区别

    make.new操作 make用于内建类型(map.slice 和channel)的内存分配.new用于各种类型的内存分配. 内建函数new本质上说跟其它语言中的同名函数功能一样:new(T)分配了零 ...

  2. golang中数组与切片的区别

    初始化:数组需要指定大小,不指定也会根据初始化的自动推算出大小,不可改变 数组: a := [...],,} a := [],,} 切片: a:= [],,} a := make([]) a := m ...

  3. golang 中Pointers Vs References

    原文: https://spf13.com/post/go-pointers-vs-references/ Pointers Vs References Some languages includin ...

  4. golang中new和make区别

    golang 中有两个内存分配机制 :new和make,二者有明显区别. new:用来初始化一个对象,并且返回该对象的首地址.其自身是一个指针.可用于初始化任何类型 make:返回一个初始化的实例,返 ...

  5. golang中sync.RWMutex和sync.Mutex区别

    golang中sync包实现了两种锁Mutex (互斥锁)和RWMutex(读写锁),其中RWMutex是基于Mutex实现的,只读锁的实现使用类似引用计数器的功能. type Mutex     f ...

  6. golang中数组指针与指针数组的区别实现

      指针数组和数组的指针,指的是两个不同的东西. 指针数组是有指针组成的数组,数组的指针是一个数组的指针. package main import "fmt" const MAX ...

  7. 【GoLang】golang 中 defer 参数的蹊跷

    参考资料: http://studygolang.com/articles/7994--Defer函数调用参数的求值 golang的闭包和普通函数调用区别:http://studygolang.com ...

  8. 说说不知道的Golang中参数传递

    本文由云+社区发表 导言 几乎每一个C++开发人员,都被面试过有关于函数参数是值传递还是引用传递的问题,其实不止于C++,任何一个语言中,我们都需要关心函数在参数传递时的行为.在golang中存在着m ...

  9. Go实战--golang中使用JWT(JSON Web Token)

    http://blog.csdn.net/wangshubo1989/article/details/74529333 之前写过关于golang中如何使用cookie的博客: 实战–go中使用cook ...

随机推荐

  1. JVM系列二(垃圾收集算法).

    一.标记-清除算法(Mark-Sweep) 这种算法分为"标记"和"清除"两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象. Mar ...

  2. [ASP.NET Core 3框架揭秘] 配置[4]:将配置绑定为对象

    虽然应用程序可以直接利用通过IConfigurationBuilder对象创建的IConfiguration对象来提取配置数据,但是我们更倾向于将其转换成一个POCO对象,以面向对象的方式来使用配置, ...

  3. SAP MM ME57界面看到的供应源跟Source List主数据不一致?

    SAP MM ME57界面看到的供应源跟Source List主数据不一致? ME57,为如下的PR单据分配供应源, 发现找不到想要分配的供应源. ME03 去看Source List主数据, 黄色标 ...

  4. canves做的时钟目前已经开源

    canves做的时钟目前已经开源 git地址: https://github.com/jidanji/canves-clock/tree/1.0.1 项目截图 时流过的时间变得有颜色,其他的没有颜色.

  5. go笔记--rpc和grpc使用

    目录 go笔记--rpc和grpc使用 rpc server.go client.go (sync) client.go (async) grpc protoc server.go client.go ...

  6. 老版本nginx存在安全漏洞,不停服务热升级

    1.场景描述 安全部通知:nginx存在"整数溢出漏洞",经测试2017年4月21日之后的版本无问题,将openresty升级到最新版本,Nginx升级到1.13.2之后的版本. ...

  7. Java程序员月薪三万,需要技术达到什么水平?

    最近跟朋友在一起聚会的时候,提了一个问题,说 Java 程序员如何能月薪达到二万,技术水平需要达到什么程度?人回答说这只能是大企业或者互联网企业工程师才能拿到.也许是的,小公司或者非互联网企业拿二万的 ...

  8. Java面试官:兄弟,你确定double精度比float低吗?

    我有一个朋友,叫老刘,戴着度数比我还高的近视镜,显得格外的"程序员":穿着也非常"不拘一格",上半身是衬衣西服,下半身是牛仔裤运动鞋. 我和老刘的感情非常好,每 ...

  9. 爬虫(四):requests模块

    1. requests模块 1.1 requests简介 requests 是一个功能强大.简单易用的 HTTP 请求库,比起之前用到的urllib模块,requests模块的api更加便捷.(本质就 ...

  10. js中关于带数字类型参数传参丢失首位数字0问题

    最近在项目中遇到一个问题,js中传带有数字的参数时,如果参数开头有数字0,会把0给去掉. 例如: 方法abc(0123456,789); 方法abc中获取的参数0123456就会变为123456. 原 ...