Введение

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

Номинальная типизация

Номинальное типирование означает, что две переменные совместимы по типу только в том случае, если их объявления ссылаются на один и тот же тип. Например, в языке C два типа структур с разными именами в одном и том же модуле перевода никогда не считаются совместимыми, даже если они имеют идентичные объявления полей. Однако C также допускает объявление `typedef`, которое создает псевдоним для существующего типа. Эти псевдонимы являются чисто синтаксическими и не различают тип и его псевдоним при проверке типов. Эта особенность, распространенная во многих языках, может привести к снижению типобезопасности, когда (например) один и тот же примитивный целочисленный тип используется в двух семантически различных контекстах. Haskell предоставляет синтаксический псевдоним в стиле C с помощью объявления `type`, а также объявление `newtype`, которое действительно вводит новый, отличный тип, изоморфный существующему.

Номинальное подтипирование

Аналогичным образом, номинальное подтипирование означает, что один тип является подтипом другого тогда и только тогда, когда это явно указано в его определении. Языки с номинальной типизацией обычно требуют, чтобы объявленные подтипы были структурно совместимы (хотя Eiffel допускает объявление несовместимых подтипов). Однако подтипы, которые структурно совместимы "случайно", но не объявлены как подтипы, не рассматриваются как подтипы. C++, C#, Java, Kotlin, Objective-C, Delphi, Swift, Julia и Rust в основном используют как номинальную типизацию, так и номинальное подтипирование. Некоторые языки с номинальным подтипированием, такие как Java и C#, позволяют объявлять классы как окончательные (или запечатанные в терминологии C#), указывая, что дальнейшее подтипирование запрещено.

Сравнение

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