简体   繁体   English

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

[英]Why does my type's String() method not get called when printing a struct field?

I have a type called Password that is simply a string.我有一种称为 Password 的类型,它只是一个字符串。 I'd like to implement the Stringer interface by providing a String() method that redacts the value.我想通过提供一个编辑值的 String() 方法来实现 Stringer 接口。

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

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

This works as I would expect, if I attempt to print a Password.如果我尝试打印密码,这将按我的预期工作。

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

But if the Password is a field within another struct, my String() method does not get called.但是如果密码是另一个结构中的一个字段,我的 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:*********}

Is there a way to make this call my String() method?有没有办法让这个调用我的 String() 方法? It appears that the code actually calls refect.Value.String() instead.看来代码实际上调用refect.Value.String()

https://play.golang.org/p/voBrSiOy-ol 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!}
}

This is from the package fmt documentation:这是来自 package fmt 文档:

When printing a struct, fmt cannot and therefore does not invoke formatting methods such as Error or String on unexported fields.打印结构时,fmt 不能也因此不会在未导出的字段上调用格式化方法,例如 Error 或 String。

The field password is not exported, so it is not inspected to figure out it implements Stringer.字段password未导出,因此未检查它是否实现了 Stringer。 Export it, and it will work:导出它,它将起作用:

type User struct {
    name     string
    Password Password
}

If you want a "failsafe" to protect yourself against accidental default formatting, you can hide your password values behind pointers by boxing a *string in your Password type.如果您想要一个“故障安全”来保护自己免受意外的默认格式的影响,您可以通过在您的密码类型中装箱一个*string来隐藏您的密码值在指针后面。

https://play.golang.org/p/vE-cEXHp2ii https://play.golang.org/p/vE-cEXHp2ii

package main

import (
    "fmt"
)

// Password a secret string that should not be leaked accidentally
type Password struct{
 *string
}
func (p Password) String() string {
    return "*********" // redact the password
}

func NewPassword(pword string) Password {
    s := new(string)
    *s = pword
    return Password{s}
}

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

func main() {
    user := User{"Fran", NewPassword("this password is safe from default formatting")}
    fmt.Printf("user = %+v \n", user)
}

Output: Output:

user = {name:Fran password:{string:0xc00008a040}} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 获取结构字段类型的简单字符串表示 - Get a simple string representation of a struct field’s type 打印golang结构时,如何忽略String()方法? - How do you ignore the String() method when printing a golang struct? 为什么fmt.Println结构体不使用其成员的String()方法 - Why fmt.Println a struct does not use String() method of it's members 如何将接口中的结构字段定义为类型约束(类型 T 没有字段或方法)? - How can I define a struct field in my interface as a type constraint (type T has no field or method)? 由类型文字定义的类型的struct字段的方法 - Method on a struct field of type defined by a type literal 当我的值是结构类型时,如何填充 map[string] interface{}? - How to populate a map[string] interface{} when my value is a struct type? Go:我在没有引用结构类型的指针变量的情况下得到一个结构字段值,为什么? - Go: I get a struct field value without deferencing the pointer variable of the struct type, why? 为什么打印时Go的地图迭代顺序会有所不同? - Why does Go's map iteration order vary when printing? 打印Go类型,忽略“String()string”方法 - Printing a Go type ignoring “String() string” method 查找与字符串匹配的结构字段类型 - Finding the matching struct field type to string
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM