Go 中通过 new(Type) 和 &Type{} 分配内存的区别

2024-04-21

考虑以下示例:

type House struct{}

func main() {
    house1 := new(House)
    house2 := &House{}
    fmt.Printf("%T | %T\n", house1, house2)
}

Output: *main.House | *main.House

两个赋值都会产生一个指向类型的指针House(来自包 main)。

来自 go docunew:

// 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.

两个作业中的内存分配在技术上是否相同?有最佳实践吗?


两个作业中的内存分配在技术上是否相同?

我不会谈论实现细节,因为这些细节可能会改变,也可能不会改变。

从语言规范的角度来看,是有区别的。

分配与new(T)遵循以下规则分配 https://golang.org/ref/spec#Allocation(我自己的注释[斜体]):

内置功能new需要一个类型T,在运行时为该类型的变量分配存储空间,并返回该类型的值*T指着它。该变量按照初始值部分中的描述进行初始化。 [它的零值]

使用复合文字进行分配&T{}遵循以下规则复合文字 https://golang.org/ref/spec#Composite_literals and 寻址 https://golang.org/ref/spec#Address_operators:

复合文字为结构体、数组、切片和映射构造值,创造新价值每次对他们进行评估时。

获取复合文字的地址会生成指向唯一变量的指针使用文字值初始化.

So both new(T) and &T{}分配存储并产生类型的值*T。然而:

  • new(T)接受任何类型,包括预先声明的标识符int and bool,如果您只需要使用一行代码初始化此类变量,这可能会派上用场:
n := new(int) // n is type *int and points to 0
b := new(bool) // b is type *bool and points to false
  • new (quoting Effective Go https://golang.org/doc/effective_go#allocation_new) "does not initialize1 that memory, it only zeros it". I.e. the memory location will have the type's zero value.
  • 复合文字只能用于结构体、数组、切片和映射
  • 复合文字可以通过显式初始化结构体字段或数组/切片/映射项来构造非零值

底线:正如Effective Go 所指出的(与上面的段落相同):

如果复合文字根本不包含任何字段,它会为该类型创建零值。表达式new(T) and &T{}是等价的。


[1]:规范和Effective Go 中术语“初始化”的使用不一致。要点是new您只能产生零值,而复合文字允许您构造非零值。显然,规格才是真相的来源。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go 中通过 new(Type) 和 &Type{} 分配内存的区别 的相关文章

  • struct{} 和 struct{}{} 在 Go 中如何工作?

    我想知道 Go 中的 struct 和 struct 是什么意思 示例如下 array index struct or make map type struct struct is a keyword https golang org re
  • golang 范围内的指针不起作用

    为什么结果是A 1 A 2 A 2 not A 1 A 2 A 3 我们不能在范围内使用指针吗 这是代码 我设置了一个指针 指向范围循环 但它失败了 package main import fmt type A struct Barry B
  • 重写 ResponseWriter 接口以捕获 HTTP 错误

    我正在用 Go 编写一个 Web 应用程序 虽然各种 mux 库提供了一种设置自定义 404 错误处理程序的方法 但没有任何其他 4xx 和 5xx 错误代码 一个建议是重写 ResponseWriter 接口中的 WriteHeader
  • Airbrake 抛出错误“pybrake - 错误 - strconv.ParseInt:解析“None”:无效语法”

    我正在尝试按照中描述的步骤在 Django 项目中使用 Airbrake 记录器https github com airbrake pybrake django integration https github com airbrake p
  • Go1编译器如何工作?

    我在一个学校项目中接触 Go 大约一个月了 我注意到 src pkg go 文件夹中的 go ast go token go parser 等包 但是 gc 编译器基于位于 src cmd gc 中的 C 文件 我的问题是关于 Go1 中用
  • 如何获取字段类型的零值

    我有一个包含许多字段的结构 我已经弄清楚如何使用反射提取字段名称 值和标签信息 我还想做的是确定字段的值是否与字段的默认值不同 目前 我有这个 有效 但有点臭 qsMap make map string interface var defa
  • 如何更改“go build”的库路径

    我正在尝试与 goncurses 一起工作 在 Centos 6 上 ncurses 库很旧 5 7 想要 5 9 所以我从源代码构建了 ncurses 并将其安装到 usr lib usr include 等中 如何告诉 go get 针
  • 使用私有 git 存储库时的 go 工作区结构

    当你不使用 github 时 我一直在尝试找出 go 代码 工作区的标准文件夹布局 结构 我可以看到如何go get在获取 github 项目时有效 但假设我自己的 git 项目不会有 github com username project
  • go:找到模块但不包含包

    我正在尝试安装 go 的网络包 但收到 不包含包错误 终端截图 我咨询过 go 模块 latest 已找到但不包含包 https stackoverflow com questions 62974985 go module latest f
  • 带 cookie 身份验证的 Gorilla websocket

    这是我的设置 我正在构建一个带有用户登录的服务 使用 Negroni 和 Gorilla 登录后 用户会获得一个会话 cookie 服务器使用该会话 cookie 来授权受保护的端点 受保护的端点之一允许用户 客户端与服务器打开 Webso
  • 在 Go 中修改导入的库

    我的问题 弹性节拍 https www elastic co products beats是一个用 Go 编写的日志传送程序的开源项目 它具有多种日志输出功能 包括控制台 Elasticsearch 和 Redis 我想将我自己的输出添加到
  • 使用 MongoDB Atlas 时 mongo-go-driver 因服务器选择超时而失败

    去版本 1 12 5 我有这个使用 node js mongo 驱动程序的代码 const MongoClient require mongodb MongoClient const uri process env MONGO HOST d
  • 在 Alpine 中找不到运行时/cgo

    In an alpine edge我安装的容器通过 RUN apk add no cache musl dev go 我试着跑go get github com golang protobuf protoc gen go then 这会导致
  • Ajax 将文件上传到内容类型为 Multipart 的 GoLang 服务器

    我正在尝试使用多部分表单将音频文件上传到 Golang 服务器 然而 Go 返回错误 multipart NextPart bufio buffer full 我相信这表明我的 Javascript 请求中存在不属于多部分格式的内容 这是我
  • 如何顺序运行 golang 测试?

    当我跑步时go test 我的输出 FAIL TestGETSearchSuccess 0 00s Location drivers api test go 283 Error Not equal 200 expected 204 actu
  • ReverseProxy取决于golang中的request.Body

    我想构建一个 http 反向代理 它检查 HTTP 主体 然后将 HTTP 请求发送到它的上游服务器 你怎么能在 Go 中做到这一点 初始尝试 如下 失败 因为 ReverseProxy 复制传入请求 修改它并发送 但正文已被读取 func
  • 在 Go 中生成随机、固定长度的字节数组

    我有一个字节数组 固定长度为4 token make byte 4 我需要将每个字节设置为随机字节 我怎样才能以最有效的方式做到这一点 这math rand就我而言 方法不提供随机字节函数 也许有一种内置的方法 或者我应该生成一个随机字符串
  • 初始化嵌套匿名结构

    我有一个 json 作为 fields time id status customerId additionalDetail pageInfo start 0 rows 1000 我想将我的结构编组到上面的 json 并创建如下结构 typ
  • 在 Go 中跟踪 HTTP 请求时指定超时

    我知道通过执行以下操作来指定 HTTP 请求超时的常用方法 httpClient http Client Timeout time Duration 5 time Second 但是 我似乎不知道在跟踪 HTTP 请求时如何执行相同的操作
  • Go io.Pipe 的缓冲版本

    有缓冲版本吗io Pipe https golang org pkg io Pipe 在标准库或第三方库中 在我推出自己的库之前 上下文 我正在尝试使用这个解决方案 https stackoverflow com a 36229262 15

随机推荐