打印指针时为什么fmt.Println不一致?

时间:2017-09-23 00:46:10

标签: pointers go

我是一位经验丰富的程序员,但从未接触过我生命中的Go。

我刚刚开始玩它,我发现fmt.Println()实际上会打印前缀为&的指针值,这很整洁。

但是,它并不适用于所有类型。我很确定这是因为它不能使用的类型是原语(或者至少,Java会称它们为Go?)。

有人知道Go fmt库中存在这种不一致行为的原因吗?我可以使用*p轻松检索该值,但出于某种原因Println不会这样做。

示例:

package main

import "fmt"

type X struct {
    S string
}

func main() {
    x := X{"Hello World"}
    fmt.Println(&x)     // &{Hello World} <-- displays the pointed-to value prefixed with &
    fmt.Println(*(&x))  // {Hello World}

    i := int(1)
    fmt.Println(&i)     // 0x10410028     <-- instead of &1 ?
    fmt.Println(*(&i))  // 1
}

1 个答案:

答案 0 :(得分:1)

&#34;技术&#34;回答你的问题可以在这里找到:

https://golang.org/src/fmt/print.go?#L839

正如您所看到的,当打印指向Array,Slice,Struct或Map类型的指针时,打印的特殊规则&#34;&amp;&#34; +值适用,但在所有其他情况下,地址都会打印出来。

至于为什么他们决定只适用这些规则,作者似乎认为对于&#34;复合物&#34;您有兴趣始终查看值的对象(即使使用指针),但对于其他简单值,情况并非如此。

你可以在这里看到推理,他们在那里添加了以前不存在的Map类型的规则:

https://github.com/golang/go/commit/a0c5adc35cbfe071786b6115d63abc7ad90578a9#diff-ebda2980233a5fb8194307ce437dd60a

我猜这与这样的事实有关,即使用例如指针来传递它们是很常见的(很多时候你只是忘了在想要打印时取消引用指针值),但没有那么常见的使用指向int或字符串来传递它们(所以如果你打印指针,你可能有兴趣看到实际的地址)。