Может быть, я могу попытаться объяснить более подробно, что все очень хорошие комментарии уже говорят:
Интерфейсы - это (в основном) указатели на ходу
Интерфейсы в go реализованы (удовлетворены), если другой тип реализует все методы, которые определяет интерфейс. Обычно это делается путем добавления методов к указателю типа, , а не типа напрямую.
type SomeInterface interface {
SomeMethod string
}
type SomeStruct struct {} // often is a struct but does not have to be
// a method on the structs pointer
func (s *SomeStruct) SomeMethod string {
return ""
}
Результаты этого:
SomeStruct
НЕ реализует SomeInterface, *SomeStruct
делает!
- Интерфейс (обычно) уже является указателем.
Ваш пример
var b bytes.Buffer
fmt.Fprintf(&b, "some text")
var w http.ResponseWriter
http.Error(w, "some error", 1)
Переменная b
типа bytes.Buffer
является struct
, как вы можете видеть из исходного кода:
type Buffer struct {
buf []byte // contents are the bytes buf[off : len(buf)]
off int // read at &buf[off], write at &buf[len(buf)]
bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation.
lastRead readOp // last read operation, so that Unread* can work correctly.
// FIXME: it would be advisable to align Buffer to cachelines to avoid false
// sharing.
}
Если вы хотите использовать его как тип io.Writer (интерфейс), вам нужно получить указатель bytes.Buffer
, поскольку (обычно) методы указателя используются в go: fmt.Fprintf(&b, "some text")
Переменная w
типа http.ResponseWriter является interface
:
type ResponseWriter interface {
Header() Header
Write([]byte) (int, error)
WriteHeader(statusCode int)
}
Поскольку интерфейсы (обычно) уже являются указателями на некоторую базовую реализацию, мы можем использовать их без указания указателя: http.Error(w, "some error", 1)
.
Инициализация интерфейса
Сам интерфейс не может быть инициализирован и использован! Для реализации интерфейса вам всегда требуется структура или другой тип, а затем вы можете инициализировать его и использовать его как тип SomeInterface
.
Например, - это реализация gin для http.ResponseWriter
. Как вы можете видеть из кода, он использует приемники указателей для своих методов. Так что http.ResponseWriter уже является указателем на структуру.
Отказ от ответственности
Это всего лишь один из способов сделать эту сложную тему простой (надеюсь). Это не технически полное или совершенно точное объяснение. Пытаться оставаться простым и в то же время максимально точным.