首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何复制结构

如何复制结构
EN

Stack Overflow用户
提问于 2018-08-01 14:22:57
回答 5查看 85.3K关注 0票数 51

我想要复制一个对象,以便我有两个相同的对象和两个不同的内存地址。我的第一次尝试失败了:

代码语言:javascript
复制
aa := a
assert.NotEqual(t, &a, &aa, "Copied items should not be the same object.") // Test fails

我能解决这个问题,这样它才能真正地复制这个结构吗?这个结构没有什么特别之处。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2018-08-01 16:27:15

在go中,原语类型和仅包含原语类型的结构是通过值复制的,因此您可以简单地将它们赋值给一个新变量(或从函数返回)。例如:

代码语言:javascript
复制
type Person struct{
  Name string
  Age  int
}

alice1 := Person{"Alice", 30}
alice2 := alice1
fmt.Println(alice1 == alice2)   // => true, they have the same field values
fmt.Println(&alice1 == &alice2) // => false, they have different addresses

alice2.Age += 10
fmt.Println(alice1 == alice2)   // => false, now they have different field values

注意,正如评论者所提到的,示例中的混淆可能是由于您正在使用的测试库的语义所致。

如果您的结构碰巧包括数组、切片或指针,则需要执行引用对象的深度副本,除非希望在副本之间保留引用。Golang不提供内置的深拷贝功能,因此您必须实现自己的功能,或者使用许多免费提供它的库中的一个。

票数 114
EN

Stack Overflow用户

发布于 2019-12-17 17:58:21

DeepCopy是一个非常繁重的操作,因此应该尽可能避免。对于下面这样的复杂结构,我们可以优化代码。

代码语言:javascript
复制
type Address struct {
    city  string
    state string
}

type Person struct {
    age     int
    name    string
    address []Address
}

p := Person{
    age:  20,
    name: "Jack",
    address: []Address{
        {
            city:  "city1",
            state: "state1",
        }, {
            city:  "city2",
            state: "state2",
        },
    },
}

var q Person
q.age = p.age
q.name = p.name
q.address = append(q.address, p.address...)
q.address[0].city = "cityx"

结果:

代码语言:javascript
复制
p object:
{20 Jack [{city1 state1} {city2 state2}]}

q object:
{20 Jack [{cityx state1} {city2 state2}]}

推论:

从上面的例子可以看出,当q被改变时,p对象并没有改变。这种方法可以用于嵌套的结构数组。

票数 7
EN

Stack Overflow用户

发布于 2021-04-17 19:20:00

小心,如果源struct实际上是一个指针,那么正常的赋值将无法工作:

代码语言:javascript
复制
package main
import "net/http"

func main() {
   a, err := http.NewRequest("GET", "https://stackoverflow.com", nil)
   if err != nil {
      panic(err)
   }
   b := a.URL
   b.Host = "superuser.com"
   println(a.URL.Host == "superuser.com")
}

相反,您需要取消引用指针:

代码语言:javascript
复制
package main
import "net/http"

func main() {
   a, err := http.NewRequest("GET", "https://stackoverflow.com", nil)
   if err != nil {
      panic(err)
   }
   b := *a.URL
   b.Host = "superuser.com"
   println(a.URL.Host == "stackoverflow.com")
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51635766

复制
相关文章

相似问题

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