为什么在打印结构字段时我的类型的String()方法没有被调用?

我有一个叫做 Password 的类型,它只是一个字符串。我想通过提供一个编辑值的 String() 方法来实现 Stringer 接口。

// Password a secret string that should not be leaked accidentally
type Password string

func (p Password) String() string {
    return "*********" // redact the password
}

如果我尝试打印密码,这将按我的预期工作。

p := Password("password not leaked here!")
fmt.Printf("password = %v n", p) 
// got...  password = ********* 

但是,如果 Password 是另一个结构中的字段,则不会调用我的 String() 方法。

// User has a name and password
type User struct {
    name     string
    password Password
}

user := User{"Fran", Password("password was leaked!")}
fmt.Printf("user = %+v n", user) 
// got...      user = {name:Fran password:password was leaked!}
// expected... user = {name:Fran password:*********}

有没有办法让这个调用我的 String() 方法?看来代码实际上是在调用refect.Value.String()

https://play.golang.org/p/voBrSiOy-ol

package main

import (
    "fmt"
)

// Password a secret string that should not be leaked accidentally
type Password string

func (p Password) String() string {
    return "*********" // redact the password
}

// User has a name and password
type User struct {
    name     string
    password Password
}

func main() {
    s := Password("password not leaked here!")
    fmt.Printf("password = %v n", s) // password = ********* 

    user := User{"Fran", Password("password was leaked!")}
    fmt.Printf("user = %+v n", user) // user = {name:Fran password:password was leaked!}
}

回答

这是来自包 fmt 文档:

打印结构时, fmt 不能,因此不会在未导出的字段上调用诸如 Error 或 String 之类的格式化方法。

该字段password未导出,因此不会对其进行检查以确定它实现了 Stringer。导出它,它将起作用:

type User struct {
    name     string
    Password Password
}


以上是为什么在打印结构字段时我的类型的String()方法没有被调用?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>