Pointers 戈朗;(*(&v))语义

Pointers 戈朗;(*(&v))语义,pointers,go,dereference,address-operator,Pointers,Go,Dereference,Address Operator,我今天遇到了一个问题,能够很快找到并解决它,但我不完全理解golang semantic为什么是这样 我用的是围棋1.10 package main import "fmt" type T struct { V int } var testT = T{} func main() { t := &(*(&testT)) t.V = 4 fmt.Println(t, testT) // test.V == t.V -> t == &

我今天遇到了一个问题,能够很快找到并解决它,但我不完全理解golang semantic为什么是这样

我用的是围棋1.10

package main

import "fmt"

type T struct {
    V int
}

var testT = T{}

func main() {
    t := &(*(&testT))
    t.V = 4
    fmt.Println(t, testT) // test.V == t.V -> t == &testT

    t1 := &testT
    t2 := *t1
    t3 := &t2
    t3.V = 5
    fmt.Println(t3, testT) // t3.V == 4 and test.T == 4 -> t3 != &testT
}
输出 我不希望与&testT相等,因此具有与t3相同的语义,但相反,如果我将中间结果存储在变量中,我发现&(*(&))序列不具有相同的语义

我的问题 这种行为的原因是什么?

当您这样做时:

t1 := &testT
t2 := *t1
t3 := &t2
t3.V = 5
t := &(*(&testT))
您获取
testT
的地址,将其存储在
t1
中。然后在下一行中创建一个新的、不同的变量
t2
,该变量的内存空间和地址与
t1
testT
的内存空间和地址不同。然后
t3
将存储这个新的、不同的变量的地址,它独立于
t1
testT

执行此操作时:

t1 := &testT
t2 := *t1
t3 := &t2
t3.V = 5
t := &(*(&testT))
获取
testT
的地址,然后取消引用指针(返回
testT
),然后再次获取该值的地址,该值将是
testT
的地址,没有创建新变量。因此
t
将指向
testT

这是正常和合乎逻辑的,没有什么令人惊讶的。规范中的相关章节:

对于指针类型为
*T
的操作数
x
,指针间接
*x
表示由
x
指向的
T
类型

因此
&testT
是变量
testT
的地址,
*(&testT)
将返回
testT
变量。再次获取其地址将与
和testT
相同

这可能暗示了采用复合文字的地址

复合文字的值生成指向用文字值初始化的唯一值的指针


当您获取复合文字(例如,
&image.Point{}
)的地址时,它确实会在引擎盖下创建一个新的匿名变量,并且该匿名变量的地址将是表达式的结果。但是获取变量的地址不会创建新变量。

这是github问题模板吗?