gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 22:05:38 25 4
gpt4 key购买 nike

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

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,是否可以像 r := Request{}一样将obj放入重置后的池中?
(我的意思是,通过此操作,struct obj可以重用,并且 gc不会收集它。)

最佳答案

Spec: Composite literals仅声明当您使用复合文字的地址时,它将指向一个未命名的变量,因此需要分配:

Taking the address of a composite literal generates a pointer to a unique variable initialized with the literal's value.



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

为了验证,我们可以使用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结构的值不需要分配。接收地址并进行分配(需要在我的64位体系结构上分配16个字节),这是 Request结构的大小,它包含一个 string类型的字段,而 string header是一个指针(8个字节)和一个长度( 8个字节)。

Go中的 Assigning值始终会创建一个副本。因此,当您分配任何值(包括结构值)时,该值将被复制,并且原始值不会由您为其分配的变量引用。

关于go - 将新结构重新分配给变量时,golang是否分配新内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62039592/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com