Введение

Класс типовых систем

Структурная система типов (или система типов, основанная на свойствах) — это основной класс типовых систем, в котором совместимость и эквивалентность типов определяются фактической структурой или определением типа, а не другими характеристиками, такими как его имя или место объявления. Структурные системы используются для определения эквивалентности типов и проверки, является ли один тип подтипом другого. Она противопоставляется номинативным системам, где сравнения основаны на именах типов или явных объявлениях, и динамической типизации (Duck typing), в которой совместимость проверяется только для той части структуры, которая используется во время выполнения.

Описание

В структурной типизации элемент считается совместимым с другим, если для каждой характеристики в типе второго элемента существует соответствующая и идентичная характеристика в типе первого элемента. В некоторых языках детали могут различаться, например, требуется ли совпадение имён характеристик. Это определение несимметрично и включает совместимость подтипов. Два типа считаются идентичными, если каждый из них совместим с другим. Например, OCaml использует структурную типизацию методов для обеспечения совместимости типов объектов. Go использует структурную типизацию методов для определения совместимости типа с интерфейсом. Функции шаблонов C++ демонстрируют структурную типизацию аргументов типов. Haxe использует структурную типизацию, но классы не поддерживают структурное подтипирование. В языках, поддерживающих полиморфизм подтипов, можно сформировать аналогичное разделение в зависимости от способа определения отношения подтипа. Один тип является подтипом другого тогда и только тогда, когда он содержит все характеристики базового типа или его подтипов. Подтип может содержать дополнительные характеристики, такие как члены, отсутствующие в базовом типе, или более строгие инварианты. Существует различие между структурной подстановкой для выведенного и невыведенного полиморфизма. Некоторые языки, такие как Haskell, не выполняют структурную подстановку в случае, когда ожидаемый тип объявлен (т.е. не выведен), например, подстановка выполняется только для функций, полиморфных на основе сигнатуры посредством вывода типов. Тогда невозможно случайно подтипировать невыведенный тип, хотя всё ещё можно обеспечить явное преобразование к невыведенному типу, которое вызывается неявно. Структурное подтипирование, вероятно, более гибкое, чем номинативное подтипирование, поскольку оно позволяет создавать ad hoc типы и протоколы; в частности, оно позволяет создать тип, являющийся супертипом существующего типа, не изменяя определение последнего. Однако это может быть нежелательно, если программист стремится создавать закрытые абстракции. Опасность структурной типизации по сравнению с номинативной заключается в том, что два независимо определенных типа, предназначенных для разных целей, но случайно обладающих одинаковыми свойствами (например, оба состоящие из пары целых чисел), могут быть признаны одним и тем же типом системой типов, просто потому, что они имеют идентичную структуру. Одним из способов избежать этого является создание отдельного алгебраического типа данных для каждого варианта использования. В 1990 году Кук и др. доказали, что наследование не является подтипированием в объектно-ориентированных языках со структурной типизацией. Проверка совместимости двух типов на основе структурной типизации — нетривиальная операция, например, требующая ведения стека ранее проверенных типов.