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.