首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当将新结构重新分配给变量时,golang是否分配新内存?

当将新结构重新分配给变量时,golang是否分配新内存?
EN

Stack Overflow用户
提问于 2020-05-27 09:16:45
回答 1查看 1.2K关注 0票数 2

当我将一个新的struct对象重新分配到一个现有变量时,地址不会改变。代码如下:

代码语言:javascript
运行
复制
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)
}

输出:

代码语言:javascript
运行
复制
0xc0004040d0
0xc0004040d0

这就像修改了Feild而没有分配新内存一样。那么,当重新分配发生时,会做什么呢?

如果我想使用sync.pool,我可以像r := Request{}一样将obj放入重置池吗?(我的意思是,使用此操作,结构obj可以重用,不会被gc收集。)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-27 10:36:33

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

复合文本的记下地址生成指向使用文本值初始化的唯一变量的指针。

当您不接受文字的地址时,只分配它,不需要分配,可以将struct值分配给已经分配了内存的变量。

为了验证,我们可以使用Go的测试框架。创建一个测试文件:

代码语言:javascript
运行
复制
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"}
    }
}

运行它时:

代码语言:javascript
运行
复制
go test -bench . -benchmem

输出:

代码语言:javascript
运行
复制
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中的赋值值总是复制。因此,当您赋值任何值(包括结构值)时,将复制该值,并且分配给它的变量不会引用原始值。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62039592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档