Рассмотрим простой интерфейс для представления объекта, который может сравнивать себя с другим значением:
type Equaler interface {
Equal(Equaler) bool
}
и этот тип, T
:
type T int
// не удовлетворяет Equaler
func (t T) Equal(u T) bool { return t == u }
В отличие от аналогичной ситуации в некоторых системах полиморфного типа, T
не реализует Equaler
. Тип аргумента T.Equal
- это T
, но буквально не обязательный тип Equaler
.
В Go система типов не поддерживает аргумент Equal
; это ответственность программиста, как иллюстрируется типом T2
, который реализует Equaler
:
type T2 int
// удовлетворяет Equaler
func (t T2) Equal(u Equaler) bool { return t == u.(T2) }
Даже это не похоже на другие системы типов, потому что в Go любой тип, который удовлетворяет Equaler
, может быть передан как аргумент T2.Equal
, и во время выполнения мы должны проверить, что аргумент имеет тип T2
. Некоторые языки предоставляют такую гарантию во время компиляции.
Связанный пример идет другим путем:
type Opener interface {
Open() Reader
}
func (t T3) Open() *os.File
В Go T3
не удовлетворяет Opener
, хотя может на другом языке.
Хотя это правда, что система типов Go делает меньше для программиста в таких случаях, отсутствие подтипов делает правила об удовлетворении интерфейса очень легко определяемыми: имена функций и сигнатуры именно таковые из интерфейса? Правило Go также легко реализовать эффективным образом. Создатели Go считают, что эти преимущества компенсируют отсутствие автоматического продвижения типа.
Читайте также:
- Go FAQ: Почему в Go нет наследования типов?
- Go FAQ: Почему в Go нет объявлений "implements"?
- Основы Go: интерфейсы
Комментариев нет:
Отправить комментарий