为了账号安全,请及时绑定邮箱和手机立即绑定

Go 快速入门指南 - make 和 new

标签:
Go

概述

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

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
全栈工程师
手记
粉丝
0
获赞与收藏
0

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消