Система структурного типа

редактировать
Системы типов
Общие понятия
Основные категории
Второстепенные категории

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

СОДЕРЖАНИЕ
  • 1 Описание
  • 2 Пример
  • 3 ссылки
  • 4 Внешние ссылки
Описание

При структурной типизации элемент считается совместимым с другим, если для каждой характеристики в пределах типа второго элемента имеется соответствующая и идентичная функция в типе первого элемента. Некоторые языки могут отличаться по деталям, например, должны ли функции совпадать по названию. Это определение не является симметричным и включает совместимость подтипов. Два типа считаются идентичными, если каждый совместим с другим.

Например, OCaml использует структурную типизацию для методов совместимости типов объектов. Go использует структурную типизацию методов для определения совместимости типа с интерфейсом. Функции шаблона C ++ демонстрируют структурную типизацию аргументов типа. Haxe использует структурную типизацию, но классы не делятся на структурные подтипы.

В языках, поддерживающих полиморфизм подтипов, подобная дихотомия может быть сформирована на основе того, как определяется отношение подтипов. Один тип является подтипом другого тогда и только тогда, когда он содержит все функции базового типа или его подтипов. Подтип может содержать добавленные функции, такие как элементы, отсутствующие в базовом типе, или более сильные инварианты.

Существует различие между структурной заменой предполагаемого и не предполагаемого полиморфизма. Некоторые языки, такие как Haskell, не заменяют структурно в случае, когда ожидаемый тип объявлен (т. Е. Не выведен), например, только заменяют функции, которые являются полиморфными на основе сигнатур посредством вывода типа. Тогда невозможно случайно подтипировать невыведенный тип, хотя все еще может быть возможно обеспечить явное преобразование в невыведенный тип, который вызывается неявно.

Структурное подтипирование, возможно, более гибкое, чем номинативное подтипирование, поскольку оно позволяет создавать специальные типы и протоколы ; в частности, он позволяет создавать тип, который является супертипом существующего типа, без изменения определения последнего. Однако это может быть нежелательно, если программист хочет создавать закрытые абстракции.

Ошибка структурной типизации по сравнению с номинативной типизацией заключается в том, что два отдельно определенных типа, предназначенные для разных целей, но случайно обладающие одинаковыми свойствами (например, оба состоят из пары целых чисел), могут считаться системой типов одним и тем же типом просто потому, что они имеют идентичную структуру. Один из способов избежать этого - создать один алгебраический тип данных для каждого использования.

В 1990 году Кук и др. Доказали, что наследование не является подтипом в объектно-ориентированных языках с структурной типизацией.

Пример

Объекты в OCaml структурно типизированы по именам и типам их методов.

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

 # let x = object val mutable x = 5 method get_x = x method set_x y = x lt;- y end;; val x: lt; get_x: int; set_x: int -gt; unit gt; = lt;objgt;

Здесь интерактивная среда выполнения OCaml для удобства распечатывает предполагаемый тип объекта. Его type ( lt; get_x : int; set_x : int -gt; unit gt;) определяется только его методами. Другими словами, тип x определяется типами методов «get_x: int» и «set_x: int -gt; unit», а не каким-либо именем.

Чтобы определить другой объект, который имеет те же методы и типы методов:

 # let y = object method get_x = 2 method set_x y = Printf.printf "%d\n" y end;; val y: lt; get_x: int; set_x: int -gt; unit gt; = lt;objgt;

OCaml считает их однотипными. Например, оператор равенства набирается так, чтобы принимать только два значения одного типа:

 # x = y;; -: bool = false

Значит, они должны быть одного типа, иначе это даже не проверка типа. Это показывает, что эквивалентность типов структурна.

Можно определить функцию, вызывающую метод:

 # let set_to_10 a = a#set_x 10;; val set_to_10: lt; set_x: int -gt; 'a;.. gt; -gt; 'a = lt;fungt;

Выведенный тип для первого аргумента ( lt; set_x : int -gt; 'a;.. gt;) интересен. Это ..означает, что первым аргументом может быть любой объект, у которого есть метод "set_x", который принимает в качестве аргумента int.

Таким образом, его можно использовать на объекте x:

 # set_to_10 x;; -: unit = ()

Можно создать другой объект, который имеет этот метод и тип метода; остальные методы не имеют значения:

 # let z = object method blahblah = 2.5 method set_x y = Printf.printf "%d\n" y end;; val z: lt; blahblah: float; set_x: int -gt; unit gt; = lt;objgt;

С ним также работает функция "set_to_10":

 # set_to_10 z;; 10 -: unit = ()

Это показывает, что совместимость таких вещей, как вызов метода, определяется структурой.

Давайте определим синоним типа для объектов только с помощью метода get_x и без других методов:

 # type simpler_obj = lt; get_x: int gt;;; type simpler_obj = lt; get_x: int gt;

Объект xне этого типа; но структурно xотносится к подтипу этого типа, поскольку xсодержит надмножество его методов. Так xможно принуждать к этому типу:

 # (x:gt; simpler_obj);; -: simpler_obj = lt;objgt; # (x:gt; simpler_obj)#get_x;; -: int = 10

Но не объект z, потому что это не структурный подтип:

# (z :gt; simpler_obj);; This expression cannot be coerced to type simpler_obj = lt; get_x : int gt;; it has type lt; blahblah : float; set_x : int -gt; unit gt; but is here used with type lt; get_x : int;.. gt; The first object type has no method get_x

Это показывает, что совместимость для расширяющихся принуждений носит структурный характер.

использованная литература
внешние ссылки
Последняя правка сделана 2023-03-19 07:20:55
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте