go - 将新结构重新分配给变量时,golang会分配新内存吗?
问题描述
当我将新的结构对象重新分配给现有变量时,地址不会改变。代码如下所示:
type Request struct {
Field string
}
func main(){
r := Request{Field: "a"}
fmt.Printf("%p\n", &r)
r = Request{Field: "b"}
fmt.Printf("%p\n", &r)
}
输出:
0xc0004040d0
0xc0004040d0
这就像在Feild
没有分配新内存的情况下进行了修改。那么当重新分配发生时,Go 会做什么呢?
如果我想使用sync.pool
,我可以像重置一样将obj放入池中r := Request{}
吗?(我的意思是通过这个操作,struct obj 可以被重用,并且不会被 . 收集gc
。)
解决方案
规范:复合文字仅声明当您获取复合文字的地址时,它将指向一个未命名的变量,因此需要分配:
当您不获取文字的地址时,只需分配它,不需要分配,可以将结构值分配给已经分配内存的变量。
为了验证,我们可以使用 Go 的测试框架。创建一个测试文件:
package main
import (
"testing"
)
type Request struct {
Field string
}
var r = Request{Field: "a"}
func BenchmarkStruct(b *testing.B) {
for i := 0; i < b.N; i++ {
r = Request{Field: "b"}
}
}
var p = &Request{Field: "a"}
func BenchmarkStructPtr(b *testing.B) {
for i := 0; i < b.N; i++ {
p = &Request{Field: "b"}
}
}
运行它:
go test -bench . -benchmem
输出:
BenchmarkStruct-4 1000000000 0.948 ns/op 0 B/op 0 allocs/op
BenchmarkStructPtr-4 32160099 37.3 ns/op 16 B/op 1 allocs/op
如您所见,Request
使用复合文字分配结构的值不需要分配。获取它的地址并分配需要 16 个字节分配(在我的 64 位架构上),这是Request
包含单个string
类型字段的结构的大小,字符串头是一个指针(8 个字节)和一个长度(8字节)。
在 Go 中赋值总是会产生副本。因此,当您分配任何值(包括结构值)时,该值将被复制,并且您分配给它的变量不会引用原始值。
推荐阅读
- flask - 气流基本身份验证 - 无法使用创建的用户登录
- asp.net - 在 aspx 页面中的 CSRF 修复
- java - 如何将自定义字段的注入添加到 FXMLLoader 的默认 ControllerFactory?
- r - Adding columns by splitting number, and removing duplicates
- java - 添加 HttpComponentsClientHttpRequestFactory 时出现 RestTemplate 404 错误
- python - 注册后 Django Rest Framework 无法登录
- python - Python KeyError JSON
- ios - 在 iOS 上的 Excel 应用程序中打开链接的 XLSM 文件
- android - Android 布局无法看到应用预览
- javascript - 使用 JSON 和 fetch API