【发布时间】: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将保存指针的副本