type S struct{}; func (s *S) String() string { return "s" }; var _ fmt.Stringer = S{}?Код не скомпилируется, потому что метод String() определен на pointer receiver (*S), а в переменную передается значение (S{}).
T имеет методы с value receiver (func (t T))*T имеет методы и с value, и с pointer receivertype S struct{}
func (s *S) String() string { return "s" }
// Не скомпилируется: S не реализует fmt.Stringer
var _ fmt.Stringer = S{}
// Скомпилируется: *S реализует fmt.Stringer
var _ fmt.Stringer = &S{}
Pointer receiver может модифицировать объект. Если бы Go позволял вызывать pointer-методы на значениях, это создало бы скрытую копию - изменения терялись бы. Поэтому компилятор запрещает это при присвоении интерфейсу.
s := S{}
s.String() // OK! Go автоматически берет &s
// Но при присвоении интерфейсу - нет:
var x fmt.Stringer = s // ошибка компиляции
var y fmt.Stringer = &s // OK
При прямом вызове метода Go автоматически берет адрес (&s), но при присвоении интерфейсу это невозможно - значение может быть неадресуемым (например, возврат функции).