I have a type called Password that is simply a string. I'd like to implement the Stringer interface by providing a String() method that redacts the value.
// 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.
// 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? It appears that the code actually calls refect.Value.String()
instead.
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!}
}