В информатике система типов является номинальной (также называется номинативной или основанной на имени ), если совместимость и эквивалентность типов данных определяются явными объявлениями и/или именем типов. Номинальные системы используются для определения эквивалентности типов, а также того, является ли тип подтипом другого. Номинальные системы типов контрастируют со структурными системами , где сравнения основаны на структуре рассматриваемых типов и не требуют явных объявлений.
Номинальная типизация означает, что две переменные совместимы по типу, если и только если их объявления называют один и тот же тип. Например, в C два struct
типа с разными именами в одной и той же единице трансляции никогда не считаются совместимыми, даже если у них идентичные объявления полей.
Однако C также допускает typedef
объявление, которое вводит псевдоним для существующего типа. Они являются просто синтаксическими и не отличают тип от его псевдонима для целей проверки типа. Эта функция, присутствующая во многих языках, может привести к потере безопасности типа, когда (например) один и тот же примитивный целочисленный тип используется двумя семантически различными способами. Haskell предоставляет синтаксический псевдоним в стиле C в форме объявления type
, а также newtype
объявление, которое вводит новый, отличный тип, изоморфный существующему типу. [1]
Аналогичным образом, номинальное подтипирование означает, что один тип является подтипом другого, если и только если он явно объявлен таковым в своем определении. Номинально типизированные языки обычно навязывают требование, чтобы объявленные подтипы были структурно совместимы (хотя Eiffel допускает объявление несовместимых подтипов). Однако подтипы, которые структурно совместимы "случайно", но не объявлены как подтипы, не считаются подтипами.
C++ , C# , Java , Kotlin , Objective-C , Delphi , Swift , Julia и Rust в основном используют как номинальную типизацию, так и номинальную подтипизацию.
Некоторые языки с номинально подтипами, такие как Java и C#, позволяют объявлять классы окончательными (или запечатанными в терминологии C#), указывая на то, что дальнейшее подтипирование не допускается.
Номинальная типизация полезна для предотвращения случайной эквивалентности типов, что обеспечивает лучшую безопасность типов, чем структурная типизация. Платой за это является снижение гибкости, поскольку, например, номинальная типизация не позволяет создавать новые супертипы без изменения существующих подтипов.