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

Go 快速入门指南 - make 和 new

时间:2022-12-24 18:37:21浏览次数:38  
标签:Map nil 初始化 make 切片 报错 Go new

概述

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

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

Go 快速入门指南 - make 和 new_Go

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()​​ 函数。

Go 快速入门指南 - make 和 new_Go_02

标签:Map,nil,初始化,make,切片,报错,Go,new
From: https://blog.51cto.com/u_15915979/5967427

相关文章

  • Go 快速入门指南 - 变长参数和指针参数
    变长参数在函数的最后一个参数的数据类型之前加上省略号 ​​...​​​ ,表示该参数的数据类型是 ​​变长类型​​​,调用该函数时可以传递任意数量 ​​(0-N)​​......
  • Go 快速入门指南 - defer 函数
    概述一个 ​​defer​​ 语句就是一个普通的函数或方法调用。 ​​defer​​ 语句保证了不论是在正常情况下(return返回),还是非正常情况下(发生错误,程序终止),函数......
  • Go 快速入门指南 - panic/recover 函数
    panic​​panic​​​ 会终止程序并退出,因此只有在发生严重的错误时才会使用 ​​panic​​。例子主动触发packagemainfuncmain(){panic("someerror...")}//$go......
  • Go 快速入门指南 - 结构体
    概述​​结构体​​​ 是将零个或多个字段(变量)组合在一起的复合数据类型,类似于面向对象语言中的 ​​对象​​。结构体以及其字段都使用 可见性 规则。语法规则type......
  • Go 快速入门指南 - 嵌套结构体
    概述Go支持将多个结构体通过嵌套的方式,组成一个大的结构体,降低了单个结构体复杂度,同时提高了结构体之间组合的灵活性。例子为了省略篇幅,本小节只使用 ​​字面量​​​ ......
  • Go 快速入门指南 - 函数
    概述​​函数​​ 是将一个或者一类问题包装为一个代码块,可以被多次调用,提高代码重用性。Go函数中声明、定义、参数、返回值这些基础概念,和其他编程语言中的一致,这里不再......
  • Go 快速入门指南 - init 函数
    概述​​init()函数​​ 是一个特殊的函数,一般称为初始化函数,不能被调用。 在每个文件里面,当程序启动或者文件被作为包引用的时候,init()函数就会自动执行,一般用来做一......
  • Go 快速入门指南 - 接口和方法
    接口Go接口是隐式实现。 对于一个数据类型,无需声明它实现了哪些接口,只需要实现接口必需的方法即可。当然了,存在一个小问题就是:我们可能无意间实现了某个接口:),所以 ​......
  • Go 快速入门指南 - 判断是否实现接口
    判断是否实现接口Go里面没有 ​​implements​​ 关键字来判断一个结构体(对象)是否实现了某个接口, 要实现类似的功能,需要用到 ​​类型断言​​。类型断言//判断......
  • Go 快速入门指南 - 零值和错误
    零值当一个变量使用 ​​var​​​ 进行声明后并未进行初始化(变量后面没有赋值符 ​​=​​)操作,会默认分配一个零值(zerovalue)。不同类型对应的零值类型零值boolf......