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

将新结构重新分配给变量时,golang会分配新内存吗?

将新结构重新分配给变量时,golang会分配新内存吗?

Go
牧羊人nacy 2022-06-06 15:53:50
当我将新的结构对象重新分配给现有变量时,地址不会改变。代码如下所示: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)}输出:0xc0004040d00xc0004040d0这就像在Feild没有分配新内存的情况下进行了修改。那么当重新分配发生时,Go 会做什么呢?如果我想使用sync.pool,我可以像重置一样将obj放入池中r := Request{}吗?(我的意思是通过这个操作,struct obj 可以被重用,并且不会被 . 收集gc。)
查看完整描述

1 回答

?
慕森王

TA贡献1777条经验 获得超3个赞

规范:复合文字仅声明当您获取复合文字的地址时,它将指向一个未命名的变量,因此需要分配:


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


当您不获取文字的地址时,只需分配它,不需要分配,可以将结构值分配给已经分配内存的变量。


为了验证,我们可以使用 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 中赋值总是会产生副本。因此,当您分配任何值(包括结构值)时,该值将被复制,并且您分配给它的变量不会引用原始值。


查看完整回答
反对 回复 2022-06-06
  • 1 回答
  • 0 关注
  • 116 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信