为什么FMT.Println在打印指针时不一致



我是一位经验丰富的程序员,但从未碰过。

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

但是,它并不是所有类型都可以做到这一点。我很确定这是因为它无法使用的类型是原始词(或者至少,Java会称呼他们,去了吗?)。

有人知道为什么在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
}

可以在此处找到您问题的"技术"答案:

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

您可以看到,在打印指针以进行数组,切片,结构或地图类型时,"&amp;"的特殊规则是 值适用,但在所有其他情况下,地址都打印了。

至于为什么他们决定仅对这些规则应用规则,作者似乎认为,对于"复合"对象,您对始终看到值(即使在使用指针时),但对于其他简单值事实并非如此。

您可以在这里看到这种原因,在其中添加了以前不存在的地图类型的规则:

https://github.com/golang/go/commit/A0C5ADC35CBFE071786B6115D63ABC7AD90578A9#DIFF-EBDA298029802333A5FB8194307CE437CE437CE437DD60A

我猜这与以下事实有关:例如,使用指针以构造它们是非常普遍的(很多次,您只是忘记在想要打印值时删除指针),但使用指针将int或字符串传递到周围的情况并不常见(因此,如果您打印指针,您可能有兴趣查看实际地址)。

最新更新