首页 > 其他分享 >Go 快速入门指南 - make 和 new

Go 快速入门指南 - make 和 new

时间:2022-12-22 16:35:38浏览次数:39  
标签:Map nil 初始化 make 切片 Go new main

概述

new() 函数为数据类型 T 分配一块内存,初始化为类型 T 的零值,返回类型为指向数据的指针,可以用于所有数据类型。

make() 函数除了为数据类型 T 分配内存外,还可以指定长度和容量,返回类型为数据的初始化结构,只限于 切片Map通道

图片

make

什么时候用

声明并初始化 切片, Map, 通道(后面会讲到)。

为什么定义

为什么专门针对切片, Map 和 通道类型定义一个 make 函数呢?因为这 3 种数据类型要求使用时必须完成初始化,未初始化就使用可能会引发错误,具体规则如下:

  • • 未初始化的切片值为 nil, 如果直接获取或设置元素数据会报错

  • • 未初始化的 Map 值为 nil, 如果直接设置元素数据会报错

  • • 未初始化的 通道 值为 nil, 发送数据和接收数据会阻塞 (详情在后面通道章节介绍)

未初始化的切片

package main

func main() {
    var s []int

    // 直接获取值: 报错
    _ = s[0]

    // 直接设置值: 同样报错
    //s[0] = 100
}

// $ go run main.go
// 输出如下 
/**
panic: runtime error: index out of range [0] with length 0
...
exit status 2
*/

未初始化的 Map

package main

func main() {
    var m map[int]string

    // 直接设置值: 报错
    m[100] = "hello world"
}

// $ go run main.go
// 输出如下 
/**
panic: panic: assignment to entry in nil map
...
exit status 2
*/

append()

为什么切片即使是 nil, 却可以调用 append() 函数呢? 因为 append() 函数内部实现中做了兼容,如果切片为 nil, 那么会先申请好需要的内存空间,然后在复制给切片,等于 覆盖掉原来的切片,这样就不会报错了。

使用 new 初始化切片和 Map

如果我们不使用 make() 函数创建切片和 Map 可以吗?当然是可以的, new() 函数可以创建任何数据类型,当然也包括切片和 Map, 但是 new() 函数返回的指针指向的是类型的 零值,对于切片和 Map 来说, 零值依然是 nil, 这又回到了上面的问题。

new() 创建的切片

package main

import "fmt"

func main() {
    s := new([]int)

    fmt.Printf("s type = %T, val = %#v\n", *s, *s)

    // 直接获取值: 报错
    _ = (*s)[0]

    // 直接设置值: 同样报错
    //s[0] = 100
}

// $ go run main.go
// 输出如下 
/**
s type = []int, val = []int(nil)
panic: runtime error: index out of range [0] with length 0
...
exit status 2
*/

new() 创建的 Map

package main

import "fmt"

func main() {
    m := new(map[int]string)

    fmt.Printf("s type = %T, val = %#v\n", *m, *m)

    // 直接设置值: 报错
    (*m)[100] = "hello world"
}

// $ go run main.go
// 输出如下 
/**
m type = map[int]string, val = map[int]string(nil)
panic: assignment to entry in nil map
...
exit status 2
*/

new

什么时候用

除了 切片, Map, 通道(后面会讲到) 以外的其他数据类型。

小结

初始化 切片Map通道 三种数据类型时,使用 make() 函数,初始化其他数据类型时,使用 new() 函数。

联系我

公众号

标签:Map,nil,初始化,make,切片,Go,new,main
From: https://www.cnblogs.com/duanbiaowu/p/16998835.html

相关文章

  • Go 快速入门指南 - 有序 Map
    概述Map 的遍历是无序的,这意味着不能依赖遍历的键值顺序。如果想实现Map遍历时顺序永远一致,一个折中的方案时预先给Map的 键 排序,然后根据排序后的键序列遍历Map......
  • Go 快速入门指南 - 变长参数和指针参数
    变长参数在函数的最后一个参数的数据类型之前加上省略号 ... ,表示该参数的数据类型是 变长类型,调用该函数时可以传递任意数量 (0-N) 的该类型的参数。一个函数......
  • Go 快速入门指南 - defer 函数
    概述一个 defer 语句就是一个普通的函数或方法调用。 defer 语句保证了不论是在正常情况下(return返回),还是非正常情况下(发生错误,程序终止),函数或方法都能够执......
  • What's new in Dubbo 3.1.4 and 3.2.0-beta.3
    在12月22日,Dubbo3.1.4和3.2.0-beta.3正式通过投票发布。本文将介绍发布的变化一览。Dubbo3.1.4版本是目前Dubbo3的最新稳定版本,我们建议所有的用户都升级到最......
  • django中间件三个了解的方法、 基于django中间件的功能设计、 cookie与session简介、
    目录django中间件三个了解的方法基于django中间件的功能设计cookie与session简介django操作cookiedjango操作cookiedjango操作sessiondjango中间件三个了解的方法1.proc......
  • GOCVHelper图像处理算法库实例整编
       GOCVHelper主要包含图像处理、图像增强和基础文件处理三个部分。由于前两个部分较具有通用性,而且我在不同项目中都进行了反复使用,为了进一步说明类库内容,这里反过来......
  • Go 快速入门指南 - 环境安装
    概述为了节省篇幅,笔者将常用的3种操作系统对应的安装教程汇总到了一起,读者可以直接选择对应内容阅读。Windows环境搭建下载1. 打开Go官网下载地址(https://go.......
  • Go-18 Golang结构体struct详解
    packagemainimport"fmt"//Golang中的结构体详解typenewIntint//自定义类型typemyInt=int//类型别名typezsIntinttypepersonstruct{ namestr......
  • 将GOCVHelper推向opencv——关于thinning函数的探索
      所以第一步就是opencvopencv_contrib联合起来。通过gitee来下载,速度非常快。https://gitee.com/mirrors/opencv_contrib/repository/archive/master.zip 配置......
  • 升级版本后,报错go: -i flag is deprecated
    环境 goversiongo1.18.6升级go版本后,本地项目起不来 将-i去掉应用,在重启,则正常启动 ......