Pointers 戈朗;(*(&v))语义
我今天遇到了一个问题,能够很快找到并解决它,但我不完全理解golang semantic为什么是这样 我用的是围棋1.10Pointers 戈朗;(*(&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 == &
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问题模板吗?