[英]Why does my type's String() method not get called when printing a struct field?
我有一種稱為 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 = *********
但是如果密碼是另一個結構中的一個字段,我的 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!}
}
這是來自 package fmt 文檔:
打印結構時,fmt 不能也因此不會在未導出的字段上調用格式化方法,例如 Error 或 String。
字段password
未導出,因此未檢查它是否實現了 Stringer。 導出它,它將起作用:
type User struct {
name string
Password Password
}
如果您想要一個“故障安全”來保護自己免受意外的默認格式的影響,您可以通過在您的密碼類型中裝箱一個*string
來隱藏您的密碼值在指針后面。
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:
user = {name:Fran password:{string:0xc00008a040}}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.