А где стоит ГО?
В языке программирования есть типы - логические, строковые, целые числа или более сложные структуры, известные как классы или структуры. Языки программирования могут быть классифицированы как типизированные, структурно типизированные или номинально типизированные, в зависимости от того, как типы оцениваются и присваиваются различным конструкциям (таким как переменные, выражения, функции, параметры функций и т. Д.) Языка программирования.
По сути, категоризация определяет, как объекты оцениваются и выводятся как определенные типы.
Языки с утиным типом используют Утиный тест, чтобы оценить, можно ли оценить объект как определенный тип. Утиный тест гласит:
Если он похож на утку, плавает, как утка, и крякает, как утка, то, вероятно, это утка.
* Я буду использовать синтаксис GO для объяснения идей - читайте эти примеры как псевдокод - он не имеет ничего общего с правилами языка GO.
Следующий фрагмент кода является примером языка Duck-Typed. Кряква - это Утка, потому что у нее есть функция кряк.
type Mallard struct { } func (m Mallard) quack() { } func makeDuckQuack(duck Duck) { duck.quack() } func main() { makeDuckQuack(Mallard{}) }
В приведенном выше примере не имеет значения, какой тип Duck - это может быть интерфейс или другой тип - но для функции makeDuckQuack единственное требование - передать объект в качестве параметра, который поддерживает функцию quack.
Для языков с утиным типом обычно нет проверок во время компиляции. Оценка и интерпретация типа происходят во время выполнения - и это может привести к ошибкам во время выполнения.
Например, следующий фрагмент кода будет компилироваться нормально, но создаст ошибку времени выполнения, поскольку Dog не выполняет quack ().
type Dog struct { } func (d Dog) bark() { } func makeDuckQuack(duck Duck) { duck.quack() } func main() { makeDuckQuack(Dog{}) }
Python и Javascript - популярные языки Duck Typed.
Языки с номинальной типизацией, находящиеся на другом конце спектра, ожидают, что прикладные программисты будут явно вызывать тип для интерпретации компилятором.
type Duck interface { quack() } type Mallard struct { //Mallard doesn't implement Duck interface } func (m Mallard) quack() { } func makeDuckQuack(duck Duck) { duck.quack() } func main() { makeDuckQuack(Mallard{}) //This will not work as Mallard doesn't explicitly implement Duck. }
В приведенном выше примере программист приложения должен специально реализовать интерфейс Duck. Можно утверждать, что явная взаимосвязь означает большую удобочитаемость.
Явное определение отношения между Mallard и Duck также означает, что пакет, содержащий структуру Mallard, зависит от пакета, содержащего Duck структура. Это может быть не всегда хорошо - и увеличивает сложность всего приложения.
Яркими примерами языков с именной типизацией являются Java, C ++.
Языки со структурной типизацией находятся где-то посередине, где программисту приложений не нужно явно определять тип для интерпретации, но компилятор языка выполняет проверки во время компиляции, чтобы гарантировать целостность программы.
type Duck interface { quack() } type Mallard struct { //Mallard doesn't implement Duck interface } func (m Mallard) quack() { } type Dog struct { } func (d Dog) bark() { } func makeDuckQuack(duck Duck) { duck.quack() } func main() { makeDuckQuack(Mallard{}) // Okay makeDuckQuack(Dog{}) // Not Okay }
В приведенном выше примере программисту не нужно указывать, что Mallard является Duck. Компилятор языка интерпретирует Mallard как Duck - потому что у него есть функция quack. И Dog не Duck -, потому что Dog не крякает.
GO - это язык со структурным типом.
Заключение
Языки с утиной типизацией обеспечивают максимальную гибкость для программиста. А программистам нужно писать минимум кода. Но эти языки могут быть небезопасными и создавать ошибки во время выполнения.
Языки с номинальной типизацией требуют от программистов явного вызова типа, но это означает больше кода и меньшую гибкость (дополнительные зависимости).
Языки со структурной типизацией обеспечивают баланс - для них требуются проверки во время компиляции и не требуется явного объявления зависимостей.
До программирования с помощью GO (структурная типизация) я в основном программировал на Java (номинальная типизация). Мне нравится гибкость, обеспечиваемая языками структурной типизации - без ущерба для безопасности типов во время компиляции.