【问题标题】:Golang &(*(&v)) semanticGolang &(*(&v)) 语义
【发布时间】:2018-08-09 18:13:41
【问题描述】:

我今天遇到了一个问题,并且能够快速找到并修复它,但不完全理解为什么 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 相同的语义,但相反,如果我将中间结果存储在变量中,我发现 &(*(&)) 序列不具有相同的语义

我的问题

这种行为的原因是什么?

【问题讨论】:

  • 这是一个github问题模板吗?

标签: pointers go dereference address-operator


【解决方案1】:

当你这样做时:

t1 := &testT
t2 := *t1
t3 := &t2
t3.V = 5

你取testT的地址,存入t1。然后在下一行 a newdistinct 变量 t2 被创建,它将具有与 t1 或 @987654331 不同的内存空间和地址@。然后t3 将存储这个新的不同变量的地址,它独立于t1testT

当你这样做时:

t := &(*(&testT))

你获取testT的地址,然后你取消引用指针(你得到testT“返回”),然后你再次获取这个值的地址,这将是testT的地址,没有创建新变量。所以t 将指向testT

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

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

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

可能暗示这一点的是采用复合文字的地址。 Spec: Composite literals:

复合文字的Taking the address 生成一个指向唯一variable 的指针,该variable 使用文字的值初始化。

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

【讨论】:

    猜你喜欢
    • 2014-01-17
    • 1970-01-01
    • 2020-01-17
    • 2015-03-26
    • 2018-09-01
    • 1970-01-01
    • 2021-10-12
    • 2018-03-22
    • 1970-01-01
    相关资源
    最近更新 更多