Spec-Zone.ru › Ada 2022
Справочник по Ada (Ada 2022)

3.8.1 Части вариантов и дискретные варианты

Тип записи с variant_part задает альтернативные списки компонентов. Каждый variant определяет компоненты для значения или значений дискриминанты, покрытых его discrete_choice_list.

Синтаксис

variant_part ::=
case discriminant_direct_name is
variant
{variant}
end case;
variant ::=
when discrete_choice_list =>
component_list
discrete_choice_list ::= discrete_choice {'|' discrete_choice}
discrete_choice ::=
choice_expression | discrete_subtype_indication | range | others

Правила разрешения имен

discriminant_direct_name должен разрешиться в обозначение дискриминанты (называемой дискриминантой variant_part), указанной в known_discriminant_part full_type_declaration, которая содержит variant_part. Ожидаемый тип для каждого discrete_choice в variant — тип дискриминанты variant_part.

Правила законности

Дискриминанта variant_part должна быть дискретного типа.
choice_expressionы, subtype_indicationы и rangeы, заданные как discrete_choice в variant_part, должны быть статическими. discrete_choice others должен появляться один в discrete_choice_list, и такой discrete_choice_list, если он появляется, должен быть последним в содержащем конструкте.
discrete_choice определяется как охватывающий значение в следующих случаях:
  • Если discrete_choice — choice_expression, то он охватывает значение, если значение равно значению choice_expression с преобразованием к ожидаемому типу.
  • Если discrete_choice — subtype_indication, то он охватывает все значения (возможно, ни одного), которые принадлежат подтипу и удовлетворяют статическим предикатам подтипа (см. 3.2.4).
  • Если discrete_choice — range, то он охватывает все значения (возможно, ни одного), которые принадлежат диапазону.
  • Значение discrete_choice others охватывает все значения ожидаемого типа, которые не покрыты предыдущими discrete_choice_list в том же конструкте.
discrete_choice_list охватывает значение, если одно из его discrete_choice охватывает это значение.
Возможные значения дискриминанты variant_part должны быть покрыты следующим образом:
  • Если дискриминанта — статический ограниченный скалярный подтип, то, за исключением экземпляра генерируемой единицы, каждый не-others discrete_choice охватывает только значения в этом подтипе, удовлетворяющие его предикатам, и каждое значение этого подтипа, удовлетворяющее его предикатам, должно быть покрыто некоторым discrete_choice (явным или с помощью others);
  • Если тип дискриминанты является потомком генерируемого формального скалярного типа, то variant_part должен иметь discrete_choice others;
  • В противном случае каждое значение базового диапазона типа дискриминанты должно быть покрыто (явным или с помощью others).
Два различных discrete_choice в variant_part не должны охватывать одно и то же значение.

Статическая семантика

Если component_list variant задается как null, то у варианта нет компонентов.
Дискриминанта variant_part считается управляющей variant_part и её variantами. Кроме того, дискриминанта производного типа управляет variant_part и её variantами, если она соответствует (см. 3.7) дискриминанте variant_part.

Динамическая семантика

Значение записи содержит значения компонентов конкретного variant только тогда, когда значение управляющей variant дискриминанты покрывается discrete_choice_list variant. Это правило применяется к любым последующим variant, которые также включены в component_list данного variant.
При инициализации объекта дискриминированного типа T по умолчанию возникает Constraint_Error, если ни одна discrete_choice_list никакого variantа variant_part T не покрывает значение дискриминанты, управляющей variant_part. Когда variant_part появляется в component_list другого variant V, эта проверка выполняется только если значение дискриминанты, управляющей V, покрывается discrete_choice_list V.
Выполнение variant_part состоит из выполнения component_list каждого variant в порядке их появления.

Примеры

Пример типа записи с частью варианта:
type Device is (Printer, Disk, Drum);
type State is (Open, Closed);
type Peripheral(Unit : Device := Disk) is
record
Status : State;
case Unit is
when Printer =>
Line_Count : Integer range 1 .. Page_Size;
when others =>
Cylinder : Cylinder_Index;
Track : Track_Number;
end case;
end record;
Примеры типов записей:
тип Drum_Unit есть Peripheral(Drum);
тип Disk_Unit есть Peripheral(Disk);
Примеры ограниченных переменных записей:
Writer : Peripheral(Unit => Printer);
Archive : Disk_Unit;


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API