Stringer interface
suggest changefmt.Stringer
interface consists of a single String() string
function:
type Stringer interface {
String() string
}
The intent is to provide a string representation of the value.
If String()
method is defined on a type, string formatting methods like fmt.Printf
use it for %s
formatting directive:
type User1 struct {
Name string
Email string
}
type User2 struct {
Name string
Email string
}
// String satisfies the fmt.Stringer interface
// Defining it on type User2 makes it available on *User2 as well
func (u User2) String() string {
return fmt.Sprintf("%s <%s>", u.Name, u.Email)
}
func main() {
u1 := &User1{
Name: "John Doe",
Email: "johndoe@example.com",
}
fmt.Printf("u1: type: %T, value: %s\n\n", u1, u1)
u2 := User2{
Name: "John Doe",
Email: "johndoe@example.com",
}
fmt.Printf("u2: type: %T, value: %s\n\n", u2, u2)
// method define on type User2 is also available on type *User2
u3 := &User2{
Name: "John Doe",
Email: "johndoe@example.com",
}
fmt.Printf("u3: type: %T, value: %s\n", u3, u3)
}
u1: type: *main.User1, value: &{John Doe johndoe@example.com}
u2: type: main.User2, value: John Doe <johndoe@example.com>
u3: type: *main.User2, value: John Doe <johndoe@example.com>
Type User1
doesn't implement Stringer
interface, so %s
displays it using the standard formatting for structs.
Type User2
implements Stringer
interface so %s
uses String()
method to get the value.
Types User2
and *User2
are not the same.
However, as a convenience, a method defined on User2
is also available on *User2
(but not the other way around).
As a result, it's better to define String()
methods on the struct type vs. a pointer to it.
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents