Руководство по Ada (Ada 2022)
12.5.1 Формальные типы-приват и производные типы
В самом общем виде категория, определяемая для формального типа-привата, — это все типы, но категория может быть ограничена только не ограниченными типами или только помеченными типами. Аналогично, категория для формального неполного типа — это все типы, но категория может быть ограничена только помеченными типами; в отличие от других формальных типов, фактический тип может быть неполно определен и не готов к замораживанию (см. 13.14). Определяемая категория для формального производного типа — это класс производности, укоренённый в типе-предка.
Синтаксис
formal_private_type_definition ::= [[абстрактный] помеченный] [ограниченный] приватный
formal_derived_type_definition ::=
[абстрактный] [ограниченный | синхронизированный] новый метка_подтипа [[и список_интерфейсов] с приватным]
[абстрактный] [ограниченный | синхронизированный] новый метка_подтипа [[и список_интерфейсов] с приватным]
Правила допустимости
Если в объявлении формального типа-генерика есть часть_известного_дискриминанта, то оно не должно включать выражение_по_умолчанию для дискриминанта.
Подтип-предок формального производного типа — это подтип, обозначаемый меткой_подтипа в формальном_объявлении_производного_типа. Для формального объявления производного типа ключевые слова с приватным должны появляться тогда и только тогда, когда тип-предок является помеченным типом; в этом случае формальный производный тип является приватным расширением типа-предка, и тип-предок не должен быть типом-класса. Аналогично, список_интерфейсов или необязательные ключевые слова абстрактный или синхронизированный должны появляться только тогда, когда тип-предок является помеченным типом. Ключевое слово ограниченный или синхронизированный должно появляться только тогда, когда тип-предок и все типы-предшественники являются ограниченными типами. Ключевое слово синхронизированный должно появляться (вместо ограниченный), если тип-предок или любой из типов-предшественников являются синхронизированными интерфейсами. Тип-предок должен быть ограниченным интерфейсом, если появляется ключевое слово синхронизированный.
Фактический тип формального производного типа должен быть потомком типа-предка и каждого предшественника формального типа. Фактический тип формального производного типа должен быть помеченным тогда и только тогда, когда формальный производный тип является приватным расширением. Если ключевое слово синхронизированный появляется в объявлении формального производного типа, фактический тип должен быть синхронизированным помеченным типом.
Если формальный подтип-приват или производный подтип является определённым, то фактический подтип также должен быть определённым. Если формальный тип неограниченный, фактический тип должен быть неограниченным.
формальное_объявление_неполного_типа объявляет формальный неполный тип. Единственный вид формального неполного типа — неполный вид. Таким образом, формальный неполный тип подпадает под те же ограничения использования, что и любой другой неполный тип — см. 3.10.1.
Для формального производного типа-генерика без части_дискриминанта фактический подтип должен быть статически совместимым с подтипом-предком. Кроме того:
- Если подтип-предок ограничен, фактический подтип должен быть ограниченным;
- Если подтип-предок является неограниченным типом доступа или составным подтипом, фактический подтип должен быть неограниченным.
- Если подтип-предок является неограниченным дискриминированным подтипом, то фактический подтип должен иметь такое же количество дискриминантов, и каждый дискриминант фактического подтипа должен соответствовать дискриминанту предка в соответствии с 3.7.
- Если подтип-предок является подтипом доступа, фактический подтип должен исключать null тогда и только тогда, когда подтип-предок исключает null.
В объявлении формального производного типа не должно быть части_известного_дискриминанта. Для формального приватного или неполного типа-генерика с частью_известного_дискриминанта:
- Фактический тип должен быть типом с таким же количеством дискриминантов.
- Фактический подтип должен быть неограниченным.
- Подтип каждого дискриминанта фактического типа должен статически соответствовать подтипу соответствующего дискриминанта формального типа.
Для формального типа-генерика с частью_неизвестного_дискриминанта фактический тип может иметь дискриминанты, хотя это не обязательно, и может быть определённым или неопределённым.
При применении правил допустимости, для определения внутри тела генерика, является ли тип неограниченным в любом частичном представлении, дискриминированный подтип считается имеющим ограниченное частичное представление, если он является потомком неопомеченного формального приватного или производного типа-генерика.
Статическая семантика
Определяемая категория для формального типа-привата следующая:
Определение типа Определённая категория
ограниченный приватный категория всех типов
приватный категория всех неограниченных типов
помеченный ограниченный приватный категория всех помеченных типов
помеченный приватный категория всех неограниченных помеченных типов
ограниченный приватный категория всех типов
приватный категория всех неограниченных типов
помеченный ограниченный приватный категория всех помеченных типов
помеченный приватный категория всех неограниченных помеченных типов
Наличие ключевого слова абстрактный определяет, может ли фактический тип быть абстрактным.
Определяемая категория для формального неполного типа — это категория всех типов, если объявление формального_типа_объявления не включает ключевое слово помеченный; в этом случае это категория всех помеченных типов.
Формальный тип-приват или производный тип — соответственно, приватный или производный тип. Формальный помеченный производный тип — это приватное расширение. Формальный приватный или производный тип является абстрактным, если в его объявлении появляется ключевое слово абстрактный.
Для формального производного типа характеристики (включая компоненты, но исключая дискриминанты, если есть новое часть_дискриминанта), предопределённые операторы и унаследованные пользователем-определённые примитивные подпрограммы определяются типом-предком и типами-предшественниками (если есть), так же как и те у производного типа определяются типом-родителя и типами-предшественниками (см. 3.4 и 7.3.1).
В экземпляре копия неявного объявления примитивной подпрограммы формального производного типа объявляет представление соответствующей примитивной подпрограммы предка или предшественника формального производного типа, даже если эта примитивная функция переопределена для фактического типа и даже если она никогда не объявлялась для фактического типа. Когда предок или предшественник формального производного типа является формальным типом, копия неявного объявления объявляет представление соответствующей скопированной операции предка или предшественника. Однако в случае формального приватного расширения метка формального типа — это метка фактического типа, поэтому если метка в вызове статически определяется как метка формального типа, то выполняемое тело будет соответствовать фактическому типу.
В экземпляре неявно составные и аддитивные аспекты (см. 13.1.1) формального типа — это аспекты фактического; для непереопределяемого аспекта формальный производный тип наследует аспект, если предок или любой предшественник имеет аспект в соответствии с правилами, указанными в 13.1.
Для префикса S, обозначающего формальный неопределённый подтип, определён следующий атрибут:
S'Определённый
S'Определённый возвращает True, если фактический подтип, соответствующий S, определён; в противном случае он возвращает False. Значение этого атрибута имеет предопределённый тип Boolean.
Динамическая семантика
В случае, когда формальный тип имеет неизвестные дискриминанты, и фактический тип — это тип-класс T'Class:
- Для определения примитивных операций формального типа каждая примитивная операция фактического типа рассматривается как подпрограмма (с врождённым соглашением вызова — см. 6.3.1), тело которой состоит из вызова диспетчеризации соответствующей операции T, с формальными параметрами в качестве фактических параметров. Если это функция, результат вызова диспетчеризации возвращается.
- Если у соответствующей операции T нет управляющих формальных параметров, то управляющая метка значения определяется контекстом вызова в соответствии с правилами для вызовов с неопределённой меткой (см. 3.9.2 и 5.2). В случае, когда метка статически определяется как метка формального типа, вызов вызывает Program_Error. Если такая функция переименована, любой вызов переименования вызывает Program_Error.
ПРИМЕЧАНИЕ 1 Фактический тип может быть абстрактным только в том случае, если формальный тип является абстрактным (см. 3.9.3).
ПРИМЕЧАНИЕ 2 Если у формального типа есть часть_дискриминанта, фактический тип может быть определённым или неопределённым. В противном случае фактический тип может быть только определённым.