Ответ
В Go утиная типизация реализуется через интерфейсы. Тип данных неявно удовлетворяет интерфейсу, если он реализует все методы, объявленные в этом интерфейсе. Явное указание implements
(как в других языках) не требуется.
Преимущество такого подхода заключается в слабой связанности (loose coupling) компонентов системы. Вы можете создавать функции, которые работают с любым типом, реализующим нужный интерфейс, что делает код более гибким, переиспользуемым и тестируемым.
Пример:
package main
import "fmt"
// Speaker определяет поведение "умение говорить"
type Speaker interface {
Speak() string
}
// Dog реализует интерфейс Speaker неявно
type Dog struct{}
func (d Dog) Speak() string { return "Гав!" }
// Human тоже реализует Speaker
type Human struct{}
func (h Human) Speak() string { return "Привет!" }
// Функция работает с любым типом, удовлетворяющим Speaker
func MakeSound(s Speaker) {
fmt.Println(s.Speak())
}
func main() {
MakeSound(Dog{})
MakeSound(Human{})
}
В этом примере и Dog
, и Human
могут быть переданы в функцию MakeSound
, потому что они оба "крякают как утка", то есть имеют метод Speak() string
. Это и есть утиная типизация в действии.