Справочное руководство по Ada 95
3.8.1 Части вариантов и дискретные варианты
Тип записи с variant_part определяет альтернативные списки компонентов. Каждый variant определяет компоненты для значений или значений дискриминанта, охватываемых его discrete_choice_list.
Синтаксис
variant_part ::=
case discriminant_direct_name is
variant
{variant}
end case;
case discriminant_direct_name is
variant
{variant}
end case;
variant ::=
when discrete_choice_list =>
component_list
when discrete_choice_list =>
component_list
discrete_choice_list ::= discrete_choice {| discrete_choice}
discrete_choice ::= expression | discrete_range | others
Правила разрешения имен
discriminant_direct_name должен разрешаться как дискриминант (называемый дискриминантом variant_part), указанный в known_discriminant_part full_type_declaration, содержащей variant_part. Ожидаемый тип для каждого discrete_choice в variant — тип дискриминанта variant_part.
Правила легальности
Дискриминант variant_part должен быть дискретного типа.
Выражения и discrete_ranges, заданные как discrete_choice в variant_part, должны быть статическими. discrete_choice others должен появляться в одиночку в discrete_choice_list, и такая discrete_choice_list, если она есть, должна быть последней в окружающем конструкте.
discrete_choice определен как охватывающий значение в следующих случаях:
- discrete_choice, являющийся expression, охватывает значение, если значение равно значению expression, преобразованному к ожидаемому типу.
- discrete_choice, являющийся discrete_range, охватывает все значения (возможно, ни одного), принадлежащие диапазону.
- discrete_choice others охватывает все значения его ожидаемого типа, не охваченные предыдущими discrete_choice_list того же конструкта.
discrete_choice_list охватывает значение, если одно из его discrete_choice охватывает это значение.
Возможные значения дискриминанта variant_part должны быть охвачены следующим образом:
- Если дискриминант — статический ограниченный скалярный подтип, то каждый discrete_choice, не являющийся others, должен охватывать только значения в этом подтипе, и каждое значение этого подтипа должно быть охвачено каким-либо discrete_choice (явно или с помощью others);
- Если тип дискриминанта является потомком порождаемого формального скалярного типа, то variant_part должен иметь discrete_choice others;
- В противном случае каждое значение базового диапазона типа дискриминанта должно быть охвачено (явно или с помощью others).
Два различных discrete_choice variant_part не должны охватывать одно и то же значение.
Статическая семантика
Если component_list variant задан как null, у варианта нет компонентов.
Дискриминант variant_part называется управляющим variant_part и его variants. Кроме того, дискриминант производного типа управляет variant_part и его variants, если он соответствует (см. 3.7) дискриминанту variant_part.
Динамическая семантика
Значение записи содержит значения компонентов конкретного variant только в том случае, если значение управляющего variant дискриминанта охватывается discrete_choice_list variant. Это правило применяется и к любым другим variant, которые сами включены в component_list данного variant.
Выполнение variant_part состоит из выполнения component_list каждого variant в порядке их появления.
Примеры
Пример типа записи с частью варианта:
type Device is (Printer, Disk, Drum);
type State is (Open, Closed);
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;
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;
Примеры подтипов записей:
subtype Drum_Unit is Peripheral(Drum);
subtype Disk_Unit is Peripheral(Disk);
subtype Disk_Unit is Peripheral(Disk);
Примеры ограниченных переменных записей:
Writer : Peripheral(Unit => Printer);
Archive : Disk_Unit;
Archive : Disk_Unit;