【问题标题】:Can you explain the behavior of this Go pointer manipulation?你能解释一下这个 Go 指针操作的行为吗?
【发布时间】:2022-01-17 15:03:18
【问题描述】:
package main
import "fmt"

type Item struct {
    val int
}

func main() {
    var items []*Item
    item := Item{}
    items = append(items, &item)
    x := items[0]
    y := *x
    x.val++
    fmt.Printf("x=%v, y=%v\n", *x, y)
}

打印出来:

x={1}, y={0}

我不明白为什么价值观不同。 x 是指向数组中第一个元素的指针,我们使用x 递增val 字段,则第一个元素已更改。 y 是第一个元素,它的 val 也应该改变,但不是吗?但是,如果将y := *x 语句移到x.val++ 之后,则值相等。为什么?

【问题讨论】:

  • 您在分配给y 之前取消引用,因此y 拥有x 指向的原始值的副本。变异x 不会影响y
  • y := *x 复制*x,即第一个项目的副本。如果您更改此副本的来源,该副本不会神奇地更改。
  • 因为 x 是指向项目对象的指针,所以 x 中的任何更改都会更改项目对象,但 y 是项目对象的副本..y 不是指向项目对象的指针。 x.val++ 正在更改项目对象。
  • @AbhijitSarkar 取消引用本身不会复制。变量初始化可以。您将取消引用的值分配给y 的事实意味着y 将保存指向任何内容的副本,因此从x 原始值“断开”y。如果您将 x 分配给 y 而不使用 deref,y 将保存指针的副本

标签: go variable-assignment


【解决方案1】:

只需要说明这一行

y := *x

这意味着从这个指针(*x)中获取值并将其分配给y,现在y有一个新的未连接到x的值。

【讨论】:

    【解决方案2】:

    因为x 已经是一个指向项目的指针。试试y := x

    【讨论】:

    • 它没有回答这个问题。 x 是问题中已经说明的 ptr,因此,您只是在说明显而易见的事情。 cmets 和接受的答案更清楚地解释了显示的行为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多