首页  >  文章  >  后端开发  >  ## 为什么我不能在 Go 中只复制带有指针接收器的类型实例?

## 为什么我不能在 Go 中只复制带有指针接收器的类型实例?

Linda Hamilton
Linda Hamilton原创
2024-10-25 05:03:02171浏览

## Why Can't I Just Copy Instances of Types With Pointer Receivers in Go?

了解指针接收器和复制实例

在 Go 中,可以使用值接收器或指针接收器来定义方法。当类型 T 的所有方法都具有 T 本身的接收者类型时,复制该类型的实例是安全的,因为调用其任何方法都必然会进行复制。

但是,当类型有带有指针接收器的方法。在这种情况下,应避免复制该类型的实例,因为它可能违反内部不变量。

复制指针的问题

让我们考虑一个示例来说明问题。假设我们有一个带有两个字段的类型 Wrapper:值 v 和指针 p。我们打算在 v 和 p 的指向值中存储相同的数字。为了确保这一点,我们提供了一个带有指针接收器的 Set 方法:

<code class="go">type Wrapper struct {
    v int
    p *int
}

func (w *Wrapper) Set(v int) {
    w.v = v
    *w.p = v
}</code>

如果我们有一个 Wrapper 实例并调用 Set 方法,它将修改 p 的指向值。但是,如果我们创建实例的副本,则副本将与原始实例共享相同的指针值 p。这意味着对任一实例的任何后续方法调用都会影响两个副本。

示例:

<code class="go">a := Wrapper{v: 0, p: new(int)}
b := a

fmt.Printf("a.v=%d, a.p=%d;  b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)

a.Set(1)
fmt.Printf("a.v=%d, a.p=%d;  b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)</code>

输出:

a.v=0, a.p=0;  b.v=0, b.p=0
a.v=1, a.p=1;  b.v=0, b.p=1

In本例中,调用 a.Set(1) 后,b 的值变得无效,因为 b.v 不等于 *b.p。这是因为 a 和 b 中的指针 p 都指向相同的基础值。

为了避免此类问题,建议在使用带有指针接收器的方法时使用指针值。或者,如果该类型只能具有值接收器,则无论方法调用如何,复制该类型的实例都是安全的。

以上是## 为什么我不能在 Go 中只复制带有指针接收器的类型实例?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn