首页 > 其他分享 >(转)Golang - new和make的使用和区别(示例详解)

(转)Golang - new和make的使用和区别(示例详解)

时间:2023-01-15 18:56:28浏览次数:47  
标签:map 示例 int make Golang 类型 new 零值

原文:https://www.cnblogs.com/beatleC/p/16081832.html

前言: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。

1、new

new 的作用是初始化一个指向类型的指针(*T),使用new函数来分配空间。传递给new 函数的是一个类型,不是一个值。返回值是指向这个新分配的零值的指针

函数定义:

func new(Type) *Type

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

复制代码
func main() {
 var i *int
 i=new(int)
 *i=10  //没有*i=10,打印的就是0
 fmt.Println(*i)
}
//运行程序,完美PASS,打印10
复制代码

再举一个栗子:

复制代码
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,它返回的永远是指向类型的指针,指向分配类型的内存地址

有new这个内置函数,可以给我们分配一块内存让我们使用,但是现实的编码中,它是不常用的,但make函数是无可替代的。

我们通常都是采用短语句声明以及结构体的字面量达到我们的目的,比如:

i:=0
u:=user{}

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

2、make

make 的作用是为 slice,map 或 chan 初始化并返回引用(T)。第一个参数是一个类型,第二个参数是长度。返回一个有初始值的对象,注意不是指针。

函数定义:

func make(Type, size IntegerType) Type

1)切片Slice的初始化

//创建一个初始元素长度为5的数组切片,元素初始值为0,并预留10个元素的存储空间: 
mySlice := make([]int, 5, 10)  

2)映射Map的初始化

//在创建时指定该map的初始存储能力,创建了一个初始存储能力为100的map
myMap = make(map[string] PersonInfo, 100) 
new的栗子:
复制代码
    //使用new创建一个map指针
    ma := new(map[string]int)
    *ma = map[string]int{}
    (*ma)["test"] = 666
    fmt.Println(*ma)    // map[test:666]
复制代码

3)通道channel的初始化

复制代码
//创建有缓存通道
ch := make(chan int, 10)
//创建无缓存通道
ch := make(chan int)
复制代码

  注意⚠️: slice, map 和 channel 的零值都是nil

  make(T, args)函数的目的与new(T)不同。它仅仅用于创建 slice, map 和 channel(引用类型),并且返回类型是 T(不是T*)的一个初始化的(不是零值)的实例。

3、总结:

new(T):创建一个没有任何数据的类型为T(零值填充)的实例,并返回该实例的指针(即地址);【用于各种类型】

make(T, args):只能创建 slice、map和channel【因为这三个类型在使用前必须被初始化】,并且返回一个初始化后(有初始值args【不是零值】)的T类型的实例,非指针*T。

标签:map,示例,int,make,Golang,类型,new,零值
From: https://www.cnblogs.com/liujiacai/p/17053947.html

相关文章

  • (转)golang 函数
    原文:https://www.cnblogs.com/duoke360/p/15663943.htmlgolang函数简介函数的go语言中的一级公民,我们把所有的功能单元都定义在函数中,可以重复使用。函数包含函数的名称......
  • golang实现的一个小游戏–猜数字
    随机生成一个数字,输入一个数字看是否匹对,匹配则结速,反之提示是大了还是小了,代码如下:packagemainimport("bufio""fmt""math/rand""os""strconv""time")var......
  • [硬核] Bootstrap Blazor Table 综合演示例子
    知识点:1.导入导出2.分页功能3.增删改查4.批量删除5.批量编辑(审核)6.列排序与列搜索7.顶部搜索实现所有列搜索8.高级搜索实现多条件搜索9.顶部与刷新与视图列10......
  • golang交叉编译
    先设置为运行平台,再设置内核类型,再编译产出常见平台有:android、darwin、linux、windows内核类型提供uname-a可以查看:amd64、arm64、386  setGOOS=linuxsetGOARC......
  • Codeforces Round #834 (Div. 3) D. Make It Round(贪心/数论)
    https://codeforces.com/contest/1759/problem/D题目大意:给定一个数字n,要求扩大至多m倍,求最大的并且最多0的数字。input106115431354161005012345264......
  • Golang开发 02
    文章目录​​一、Golang开发工具​​​​二、visualstudiocode安装(VScode)​​​​1、安装window​​​​2、安装mac、linux​​一、Golang开发工具#1、Visualstudio......
  • 【Linux操作系统】自动化编译make和Makefile
    文章目录​​一.make/makefile简介​​​​1.什么是make,makefile?​​​​2.为什么要有make/makefile?​​​​二.makefile文件规则​​​​1.基本规则​​​​2.举一个例......
  • Cmake项目结构
    -project-CMakeLists.txt-include/-project/*.h-src/-CMakeLists.txt-*.cpp-apps/-CMakeLists.txt-app.cpp-tests/CMakeLists.txttest.cpp-extern/googletes......
  • Flex/AS3/flash player支持屏蔽右键菜单,自定义菜单,并设置相应的菜单事件(示例,图解)
    播放器版本11.2以后支持右键菜单屏蔽及自定义菜单1.更新播放器,11.2以上版本​​http://download.macromedia.com/get/flashplayer/updaters/11/playerglobal11_3.swc......
  • flex 3 combobox 实现关键字过滤搜索-代码示例
    <?xmlversion="1.0"encoding="utf-8"?><s:Applicationxmlns:fx="http://ns.adobe.com/mxml/2009"xmlns:s="library://ns.adobe.com/flex/spark"xmlns:mx="......