Golang &(*(&v)) 语义
Golang &(*(&v)) semantic
我今天遇到了一个问题,能够找到它并快速修复它,但不完全理解为什么 golang 语义是这样的。
我正在使用 Go 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
}
输出
&{4} {4}
&{5} {4}
我期望不等于 &testT,因此具有与 t3 相同的语义,但相反,如果我将中间结果存储在变量中,我发现 &(*(&)) 序列没有相同的语义
我的问题
这种行为的原因是什么?
当你这样做时:
t1 := &testT
t2 := *t1
t3 := &t2
t3.V = 5
你取testT
的地址,存入t1
。然后在下一行 a new, distinct 变量 t2
被创建,它将有一个不同的内存 space和地址比t1
或testT
。然后 t3
将存储这个新的不同变量的地址,它独立于 t1
或 testT
.
当你这样做时:
t := &(*(&testT))
你取 testT
的地址,然后取消引用指针(你得到 testT
"back"),然后你再次取这个值的地址,这将是地址testT
、没有创建新变量。所以 t
将指向 testT
.
这很正常,也合乎逻辑,没有什么奇怪的。规范中的相关部分:Address operators:
For an operand x
of pointer type *T
, the pointer indirection *x
denotes the variable of type T
pointed to by x
.
所以&testT
就是变量testT
的地址,*(&testT)
就会给你返回testT
变量。再次获取其地址将与 &testT
.
相同
可能暗示这一点的是采用复合文字的地址。 Spec: Composite literals:
Taking the address of a composite literal generates a pointer to a unique variable initialized with the literal's value.
当您获取复合文字的地址(例如 &image.Point{}
)时,这确实会在幕后创建一个新的匿名变量,并且该匿名变量的地址将是表达式的结果。但是取一个变量的地址并不会创建一个新变量。
我今天遇到了一个问题,能够找到它并快速修复它,但不完全理解为什么 golang 语义是这样的。
我正在使用 Go 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
}
输出
&{4} {4}
&{5} {4}
我期望不等于 &testT,因此具有与 t3 相同的语义,但相反,如果我将中间结果存储在变量中,我发现 &(*(&)) 序列没有相同的语义
我的问题
这种行为的原因是什么?
当你这样做时:
t1 := &testT
t2 := *t1
t3 := &t2
t3.V = 5
你取testT
的地址,存入t1
。然后在下一行 a new, distinct 变量 t2
被创建,它将有一个不同的内存 space和地址比t1
或testT
。然后 t3
将存储这个新的不同变量的地址,它独立于 t1
或 testT
.
当你这样做时:
t := &(*(&testT))
你取 testT
的地址,然后取消引用指针(你得到 testT
"back"),然后你再次取这个值的地址,这将是地址testT
、没有创建新变量。所以 t
将指向 testT
.
这很正常,也合乎逻辑,没有什么奇怪的。规范中的相关部分:Address operators:
For an operand
x
of pointer type*T
, the pointer indirection*x
denotes the variable of typeT
pointed to byx
.
所以&testT
就是变量testT
的地址,*(&testT)
就会给你返回testT
变量。再次获取其地址将与 &testT
.
可能暗示这一点的是采用复合文字的地址。 Spec: Composite literals:
Taking the address of a composite literal generates a pointer to a unique variable initialized with the literal's value.
当您获取复合文字的地址(例如 &image.Point{}
)时,这确实会在幕后创建一个新的匿名变量,并且该匿名变量的地址将是表达式的结果。但是取一个变量的地址并不会创建一个新变量。