Stringer interface

suggest change

fmt.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.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:



Table Of Contents