Golang&(*(V))的语义

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang&(*(V))的语义相关的知识,希望对你有一定的参考价值。

我今天遇到了一个问题,并且能够快速找到并修复它,但是并不完全理解为什么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
}

Output

&{4} {4}
&{5} {4}

我期望不要等于&testT所以有与t3相同的语义,但是如果我将中间结果存储在变量中,我会看到&(*(&))序列没有相同的语义

My question

这种行为的原因是什么?

答案

当你这样做:

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

你拿testT的地址,把它存放在t1。然后在下一行中创建一个新的,不同的变量t2,它将具有与t1testT不同的内存空间和地址。然后t3将存储这个新的,不同的变量的地址,该变量独立于t1testT

当你这样做:

t := &(*(&testT))

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

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

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

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

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

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

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

以上是关于Golang&(*(V))的语义的主要内容,如果未能解决你的问题,请参考以下文章

golang goroutine例子[golang并发代码片段]

golang代码片段(摘抄)

代码片段 - Golang 实现简单的 Web 服务器

代码片段 - Golang 实现集合操作

推荐 3 款 Golang 语义化版本库

json [Golang] golang #golang #snippets中有用的片段