目录

一、new

二、make

三、new 和 make的区别


许多小伙伴在刚接触 Golang 的时候不理解为什么会有两个用于分配内存的函数: new 和 make,俗话说:存在即合理,下面就来详细说明下这两者的区别。

一、new

先看函数声明:

func new(Type) *Type

new 是 Golang 的内建函数,用于分配内存,其中,第一个参数是类型,返回值是类型的指针,其值被初始化为“零”(类型对应的零值,int 初始化为0,bool初始化为 false 等)。

例如:

package main
import "fmt"func main() {id := new(int)name := new(string)flag := new(bool)fmt.Printf("id type: %T  value: %v\n", id, *id)fmt.Printf("name type: %T  value: %v\n", name, *name)fmt.Printf("flag type: %T  value: %v\n", flag, *flag)
}

输出:

id type: *int  value: 0
name type: *string  value:
flag type: *bool  value: false

从上述例子可以看到,初始化的“零”值根据类型不同而不同,整数初始化为 0,字符串初始化为空,bool类型初始化为 false。

二、make

先看函数声明:

func make(t Type, size ...IntegerType) Type

make 是 Golang 的内建函数,用于分配初始化 slice、map 以及 channel 类型的对象,三种类型都是结构。返回值为类型,而不是指针。

slice 源码结构:

type slice struct {array unsafe.Pointer  //指针len   int             //长度cap   int             //容量
}

map 源码结构:

// A header for a Go map.
type hmap struct {// Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go.// Make sure this stays in sync with the compiler's definition.count     int // # live cells == size of map.  Must be first (used by len() builtin)flags     uint8B         uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for detailshash0     uint32 // hash seedbuckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growingnevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)extra *mapextra // optional fields
}

channel 源码结构:

type hchan struct {qcount   uint           // total data in the queuedataqsiz uint           // size of the circular queuebuf      unsafe.Pointer // points to an array of dataqsiz elementselemsize uint16closed   uint32elemtype *_type // element typesendx    uint   // send indexrecvx    uint   // receive indexrecvq    waitq  // list of recv waiterssendq    waitq  // list of send waiters// lock protects all fields in hchan, as well as several// fields in sudogs blocked on this channel.//// Do not change another G's status while holding this lock// (in particular, do not ready a G), as this can deadlock// with stack shrinking.lock mutex
}

例如:

package mainimport "fmt"func main() {//mapfmt.Println("map:")var nameId = make(map[string]int, 0)fmt.Printf("nameId \ntype: %#v\n", nameId)nameId["Golang"] = 1nameId["C++"] = 2nameId["PHP"] = 3for name, id := range nameId {fmt.Printf("name = %v, id = %v\n", name, id)}// slicevar hobby = make([]string, 2, 100) // 其中 2是长度,100是容量hobby[0] = "打篮球"hobby[1] = "乒乓球"fmt.Println("\nslice:")fmt.Printf("length = %v  caps = %v\n", len(hobby), cap(hobby))for _, name := range hobby {fmt.Println(name)}// channelch := make(chan int, 3)ch <- 1ch <- 2ch <- 8close(ch)fmt.Println("\nchannel:")for val := range ch { // 遍历数据fmt.Println(val)}
}

输出:

[root@localhost test]# go run main.go
map:
nameId
type: map[string]int{}
name = Golang, id = 1
name = C++, id = 2
name = PHP, id = 3slice:
length = 2  caps = 100
打篮球
乒乓球channel:
1
2
8
[root@localhost test]#

三、new 和 make的区别

1. new 和 make 都用于分配内存;

2. new 和 make 都是在堆上分配内存;

3. new 对指针类型分配内存,返回值是分配类型的指针,new也可以对 slice 、map、channel 分配内存;

4. make 仅用于 slice、map和 channel 的初始化,返回值为类型本身,而不是指针;

Golang make和new的区别详解相关推荐

  1. HashTable和HashMap的区别详解

    HashTable和HashMap的区别详解 一.HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同 ...

  2. java mod %区别_Java中 % 与Math.floorMod() 区别详解

    %为取余(rem),Math.floorMod()为取模(mod) 取余取模有什么区别呢? 对于整型数a,b来说,取模运算或者取余运算的方法都是: 1.求 整数商: c = a/b; 2.计算模或者余 ...

  3. 关于numpy中eye和identity的区别详解

    https://www.jb51.net/article/175386.htm np.identity(n, dtype=None) np.eye(N, M=None, k=0, dtype=< ...

  4. php为什么需要配置路由器,laravel 配置路由 api和web定义的路由的区别详解

    1.路由经过中间件方面不同 打开kerenl.php就可以看到区别 protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware ...

  5. python协程详解_对Python协程之异步同步的区别详解

    一下代码通过协程.多线程.多进程的方式,运行代码展示异步与同步的区别. import gevent import threading import multiprocessing # 这里展示同步和异 ...

  6. Jar/War/Ear等包的作用与区别详解

    Jar/War/Ear等包的作用与区别详解 以客户角度来看,jar文件就是一种封装格式,用户不需要知道jar包中有多少个.class格式的文件及每个文件中的功能与作用,也可以得到相应的访问的结果.ja ...

  7. Java中print、printf、println的区别 详解

    Java中print.printf.println的区别详解 printf主要是继承了C语言的printf的一些特性,可以进行格式化输出 print就是一般的标准输出,但是不换行 println和pr ...

  8. axios请求接口http_使用axios请求接口,几种content-type的区别详解

    axios的使用 安装(一般使用框架的话, 脚手架都集成了) $ npm install axios 请求示例 // POST axios.post('/user', { firstName: 'Fr ...

  9. vue 事件调用 传参_对vue下点击事件传参和不传参的区别详解

    如下所示: {{btn_text1}} {{btn_text2}} var _vm = new Vue({ data : { btn_text1 : '点击1' , btn_text2 : '点击2' ...

最新文章

  1. 【实验】 策略路由配置案例
  2. ASP.NET(C#) 四舍五入、进一法、舍位(取整,舍去小数,向负无穷舍入)函数
  3. 飞鸽传书最新C++源码:这两个消息钩子
  4. 把你的科室做成蛋糕,你能想象是什么样子吗?
  5. LintCode 69---二叉树的层次遍历
  6. 游戏可以html+上运行吗,运行多个,如果在HTML游戏
  7. educoder第六章 关联挖掘 实验二:FP-growth
  8. HDU 2457 DNA repair(AC自动机 + DP)题解
  9. XP SP3多数功能借鉴Vista 安装将无需密码
  10. MATLAB —— 低通滤波器设计与信号滤波
  11. 浏览器 cookie 和 session 的认识
  12. sketch up rbs/rbz/rb插件安装方法
  13. 如何将自己的录音形成二维码,用微信扫一下就能听?
  14. Python 与 Matlab 矩阵操作对应表
  15. comboFM: leveraging multi-way interactions for systematic prediction of drug combination effects
  16. Android加速度传感器原理
  17. java画太极加图片_通过Java 画一个太极图
  18. 淘小铺是什么?为什么一夜火爆朋友圈
  19. Android运行虚拟机怎样解锁,vm 虚拟机 android 如何解锁
  20. python笔记 - EasyGui的使用

热门文章

  1. [转]写一个块设备驱动(第六章)
  2. 360doc无法复制 360文档 复制方法
  3. stm32专题五:时钟树(三)自定义配置HSE时钟 超频
  4. java中inputstream_Java InputStream类
  5. Flex布局 text-align 失效的问题
  6. dw建立站点连接mysql_DW中站点的使用
  7. Android 沾包处理,以串口接入为例 (usb-serial-for-android)
  8. JS创建、获取、删除 cookie 方法
  9. npm install -g 和 npm install 区别?
  10. 全球及中国PCCP管市场运作模式与投资战略建议报告2022年