猿问

有没有一种惯用的方法来 malloc 和 memcpy 结构?

在纯 C 语言中,如果我想要一个结构的浅堆副本,我malloc()会这样做memcpy()。


在 Go 中,我想我必须这样做:


original := Data{...}

copy := &Data{}     // malloc

*copy = original    // memcpy

但这对我来说并不好看,也不惯用。什么是“正确”的做法?


慕妹3146593
浏览 154回答 2
2回答

幕布斯6054654

惯用的方法是做一个简单的赋值,让编译器copy在执行逃逸分析后在堆上分配:original := Data{...}copy := originalreturn &copy  // Or call some function with &copy as a parameter在注意到它copy被引用使用并且超过堆栈时,Go 将自动在堆上而不是在堆栈上分配它(当然,复制仍然正确完成)我们实际上不再关心堆,而是让编译器根据逃逸分析在需要时分配它。我们唯一关心的是副本本身。您可以在godbolt上看到一个示例:给出以下简单代码:func main() {   type Data struct{        foo string    }    original := Data{"hi"}    copy := original    copyPtr := &copy    fmt.Println(copyPtr)}Go 会自动copy在堆上分配:        call    runtime.newobject(SB)我们还可以通过在编译时传递额外的标志来显示转义和内联决策,从而看到这一点:$ go build -gcflags '-m' ...../main.go:11:2: moved to heap: copy...注意:复制是一个内置函数。避免重复使用名称可能是个好主意(它工作得很好,但这不是很好的做法)。

尚方宝剑之说

Golang 中的结构变量可以简单地通过赋值语句复制到另一个:https://play.golang.org/p/4Zcbxhy5UoBpackage mainimport (    "fmt")type User struct {    name string}func main() {    u1 := User{name: "foo"}        u2 := u1    u2.name = "bar"        fmt.Println("u1: ", u1)    fmt.Println("u2: ", u2)}输出:u1:  {foo}u2:  {bar}
随时随地看视频慕课网APP

相关分类

Go
我要回答