【问题标题】:Why fmt.Println a struct does not use String() method of it's members为什么 fmt.Println 结构不使用其成员的 String() 方法
【发布时间】:2017-08-06 12:55:57
【问题描述】:
package main

import (
    "fmt"
)

type bar struct {
}

func (b bar) String() string {
    return "bar"
}

type foo struct {
    b []*bar
    bb *bar
}

func main() {
    f := foo{b: []*bar{&bar{}}, bb:&bar{}}
    fmt.Println(f, f.b, f.bb)
}

为什么是结果

{[0x176f44] 0x176f44} [条]条

没有

{[条]条}[条]条

这背后有什么原因吗?它看起来很容易实现并且有利于可读性。

【问题讨论】:

    标签: go


    【解决方案1】:

    您的代码中有几个问题。您在未导出的 bar 上定义 Stirng,您的字段也未导出。这有效:

    type Bar struct {
    }
    
    func (b Bar) String() string {
        return "bar"
    }
    
    type foo struct {
        B  []Bar
        BB Bar
    }
    
    func main() {
        f := foo{B: []Bar{Bar{}}, BB: Bar{}}
        fmt.Println(f)
    }
    

    游乐场:https://play.golang.org/p/OhoIcB7cA3.

    这也适用于*Bar

    【讨论】:

    • 谢谢!你能解释为什么它们必须被出口吗?如果它打印出一些东西,那么 fmt.Println 已经在使用反射来检查未导出的字段,那么为什么它不只打印出 String() 版本呢? json.Marshal 类似,但未导出的字段不会被序列化。
    • @HelinWang 如果它打印{},那么它不会访问未导出的字段,它只知道它是一个结构。事实上,我认为您无法使用reflect 访问未导出的字段。这就是与您的数据一起使用的包(如 fmtencoding/json)需要导出字段的原因。
    • 打印{[0x176f44] 0x176f44}。我认为反射可以访问未导出的字段:stackoverflow.com/questions/17981651/…
    • 我想我读错了未导出的字段。所以我真的不知道为什么它不使用String()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    相关资源
    最近更新 更多