前言

本文主要给大家介绍了Go语言中函数new与make的使用和区别,关于Go语言中new和make是内建的两个函数,主要用来创建分配类型内存。在我们定义生成变量的时候,可能会觉得有点迷惑,其实他们的规则很简单,下面我们就通过一些示例说明他们的区别和使用,话不多说了,来一起看看详细的介绍吧。

变量的声明

var i int
var s string

变量的声明我们可以通过var关键字,然后就可以在程序中使用。当我们不指定变量的默认值时,这些变量的默认值是他们的零值,比如int类型的零值是0,string类型的零值是"",引用类型的零值是nil。

对于例子中的两种类型的声明,我们可以直接使用,对其进行赋值输出。但是如果我们换成引用类型呢?

package main
import (
"fmt"
)
func main() {
var i *int
*i=10
fmt.Println(*i)
}

这个例子会打印出什么?0还是10?。以上全错,运行的时候会painc,原因如下:

panic: runtime error: invalid memory address or nil pointer dereference

从这个提示中可以看出,对于引用类型的变量,我们不光要声明它,还要为它分配内容空间,否则我们的值放在哪里去呢?这就是上面错误提示的原因。

对于值类型的声明不需要,是因为已经默认帮我们分配好了。

要分配内存,就引出来今天的new和make。

new

对于上面的问题我们如何解决呢?既然我们知道了没有为其分配内存,那么我们使用new分配一个吧。

func main() {
var i *int
i=new(int)
*i=10
fmt.Println(*i)
}

现在再运行程序,完美PASS,打印10。现在让我们看下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

它只接受一个参数,这个参数是一个类型,分配好内存后,返回一个指向该类型内存地址的指针。同时请注意它同时把分配的内存置为零,也就是类型的零值。

我们的例子中,如果没有*i=10,那么打印的就是0。这里体现不出来new函数这种内存置为零的好处,我们再看一个例子。

func main() {
u:=new(user)
u.lock.Lock()
u.name = "张三"
u.lock.Unlock()
fmt.Println(u)
}
type user struct {
lock sync.Mutex
name string
age int
}

示例中的user类型中的lock字段我不用初始化,直接可以拿来用,不会有无效内存引用异常,因为它已经被零值了。

这就是new,它返回的永远是类型的指针,指向分配类型的内存地址。

make

make也是用于内存分配的,但是和new不同,它只用于chan、map以及切片的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。

注意,因为这三种类型是引用类型,所以必须得初始化,但是不是置为零值,这个和new是不一样的。

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

从函数声明中可以看到,返回的还是该类型。

二者异同

所以从这里可以看的很明白了,二者都是内存的分配(堆上),但是make只用于slice、map以及channel的初始化(非零值);而new用于类型的内存分配,并且内存置为零。所以在我们编写程序的时候,就可以根据自己的需要很好的选择了。

make返回的还是这三个引用类型本身;而new返回的是指向类型的指针。

其实new不常用

所以有new这个内置函数,可以给我们分配一块内存让我们使用,但是现实的编码中,它是不常用的。我们通常都是采用短语句声明以及结构体的字面量达到我们的目的,比如:

i:=0
u:=user{}

这样更简洁方便,而且不会涉及到指针这种比麻烦的操作。

make函数是无可替代的,我们在使用slice、map以及channel的时候,还是要使用make进行初始化,然后才可以对他们进行操作。

参考

https://www.jb51.net/article/126703.htm

[转]Go语言中的make和new的更多相关文章

  1. C语言中,头文件和源文件的关系(转)

    简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...

  2. C 语言中 setjmp 和 longjmp

    在 C 语言中,我们不能使用 goto 语句来跳转到另一个函数中的某个 label 处:但提供了两个函数——setjmp 和 longjmp来完成这种类型的分支跳转.后面我们会看到这两个函数在处理异常 ...

  3. c语言中的scanf在java中应该怎么表达,Scanner类。

    1 java是面向对象的语言 它没有像C语言中的scanf()函数,但是它的类库中有含有scanf功能的函数 2 java.util包下有Scanner类 Scanner类的功能与scanf类似 3 ...

  4. C语言中do...while(0)的妙用(转载)

    转载来自:C语言中do...while(0)的妙用,感谢分享. 在linux内核代码中,经常看到do...while(0)的宏,do...while(0)有很多作用,下面举出几个: 1.避免goto语 ...

  5. C语言中,定义的含义?声明的含义?它们之间的区别是什么?

    在C语言中,对于定义和声明,也许我们非常的熟悉,但不一定真正的了解! 定义的含义:所谓定义,就是创建(编译器)一个对象,为这个对象分配一块内存空间并取名,也就是我们平常所说的变量名或对象名,一旦这个名 ...

  6. C++中函数的默认参数和C语言中volatile的学习

    1.函数默认参数 1 int func(int a,int b=10) 2 { 3 return a*b; 4 } 5 6 int main() 7 { 8 int c=func(2); 9 cout ...

  7. C语言中qsort函数用法

    C语言中qsort函数用法-示例分析    本文实例汇总介绍了C语言中qsort函数用法,包括针对各种数据类型参数的排序,非常具有实用价值非常具有实用价值. 分享给大家供大家参考.C语言中的qsort ...

  8. c语言中time相关函数

    工作中遇到的函数: int seed = time(NULL); srand(seed); signal(SIGINT, stop); signal(SIGUSR1, sig_usr1); 搜time ...

  9. C语言中的static 详细分析

    转自:http://blog.csdn.net/keyeagle/article/details/6708077/ google了近三页的关于C语言中static的内容,发现可用的信息很少,要么长篇大 ...

  10. C语言中if语句

    C语言if语句后面的表达式 C语言中if关键字之后(即括号内)均为表达式. 该表达式通常是逻辑表达式或关系表达式,但也可以是其它表达式,如赋值表达式等,甚至也可以是一个变量,这些变量的值都换算成了逻辑 ...

随机推荐

  1. C#选择文件、选择文件夹、打开文件

    1.选择文件用OpenDialog OpenFileDialog dialog = new OpenFileDialog(); dialog.Multiselect = true;//该值确定是否可以 ...

  2. mybatis自动生成mapper和pojo

    1.在resources下新建generatorConfig.xml <?xml version="1.0" encoding="UTF-8"?> ...

  3. 潭州课堂25班:Ph201805201 django 项目 第十五课 用户注册功能后台实现 (课堂笔记)

    前台:判断用户输入 ,确认密码,手机号, 一切通过后向后台发送请求, 请求方式:post 在 suers 应用下的视图中: 1,创建个类, 2,创建 GET 方法,宣言页面 3,创建  POST 方法 ...

  4. [PA2014]Bazarek

    [PA2014]Bazarek 题目大意: 有\(n(n\le10^6)\)件商品,\(m(m\le10^6)\)次询问.每次询问若选出其中的\(k\)个,要求它们的总价为奇数,求最大可能的总价. 思 ...

  5. 更改pip安装源的镜像解决安装总是timeout的情况(pip 豆瓣镜像源)

    由于国外的pip源总是由于各种原因不能被访问或者网速过慢,而造成的timeout错误 解决方法是修改pip的配置文件(如果没有配置文件在相应的地方新建,配置文件的路径和名字参考这里),设置安装包时候访 ...

  6. pypthon 3.6.5 绘制柱状图中文乱码的基本、根本、高效之解决方案~

    最近在使用做一些数据统计.分析时需要用到画图,这里随大流使用matlab强大的python平台绘图组件pyplot来实现. 然而在使用过程中遇到中文显示框框的问题,对于有强迫症的我简直不能忍啊~ 下面 ...

  7. Flask请求request

    Flask中的request是一个公共变量,需要导入request from flask import Flask,request 接收url中的参数 @app.route("/req&qu ...

  8. 移动游戏ui设计(二)--游戏世界的基本法则

    游戏世界的基本法则游戏体验的层次感很重要,制作一款趣味性强,宗旨明确的游戏并不简单. l  风格统一性:要先明白游戏的game genres,因为游戏类型与风格密切联系.常见游戏类型有:动作类.冒险类 ...

  9. 牛客网--C++-2017/8/19

    “\t\v\\0”长度=4:\0:字符串结束符:\\0:\将\0进行了转义,所以\0是两个字符 类的友元函数的访问权限跟类内部的方法相同,但是友元函数不属于本类的对象,一般它是另一个类的成员函数,不能 ...

  10. 获取gcc和clang的内置宏定义

    下面是对Gcc的内置宏定义的解释: https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html https://github.co ...