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:
https://codeeval.dev/gist/594353d3b96a03c3152d573b33458b48
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.