Справочник по Ada (Ada 2022)
4.3.1 Агрегаты записей
В агрегате записи указывается значение для каждого компонента записи или значения расширения записи, используя именованные или позиционные ассоциации.
Синтаксис
record_component_association_list ::=
record_component_association {, record_component_association}
| null record
record_component_association {, record_component_association}
| null record
record_component_association ::=
[component_choice_list =>] expression
| component_choice_list => <>
[component_choice_list =>] expression
| component_choice_list => <>
Ассоциация компонента записи является именованной ассоциацией, если она содержит component_choice_list; в противном случае это позиционная ассоциация. Все позиционные ассоциации должны предшествовать именованным. Если имеется именованная ассоциация с component_choice_list others, она должна стоять последней.
В record_component_association_list для record_aggregate, если имеется только одна ассоциация, она должна быть именованной.
Правила разрешения имен
Ожидаемый тип для агрегата записи должен быть единственным типом записи или расширением записи.
Для record_component_association_list агрегата записи все компоненты составного значения, определенного агрегатом, являются необходимыми; для списка ассоциаций агрегата расширения только те компоненты, которые не определены выражением предка или подтипом, являются необходимыми (см. 4.3.2). Каждый component_selector_name в record_component_association агрегата записи или агрегата расширения должен обозначать необходимый компонент (включая, возможно, дискриминант). Каждый component_selector_name в record_component_association агрегата изменения записи (см. 4.3.4) должен обозначать компонент типа агрегата, не являющийся дискриминантом.
Ожидаемый тип выражения expression ассоциации компонента записи соответствует типу сопоставленного компонента(ов):
- Для позиционной ассоциации — компонент (включая, возможно, дискриминант) в соответствующей относительной позиции (в области объявления типа), учитывая только необходимые компоненты;
- Для именованной ассоциации с одним или несколькими component_selector_name — соответствующий именованный компонент(ы);
- Для именованной ассоциации со словом others — все необходимые компоненты, не связанные с предыдущими ассоциациями.
Правила допустимости
Если тип агрегата записи является расширением записи, то он должен быть потомком типа записи через одно или несколько расширений записи (и без частных расширений).
Список ассоциаций компонентов записи должен быть null record только если он используется в агрегате записи или агрегате расширения, и для этого списка нет необходимых компонентов.
Для агрегата записи или агрегата расширения каждая ассоциация компонента записи, отличная от выбора others с <>, должна иметь, по меньшей мере, один сопоставленный компонент, а каждый необходимый компонент должен быть связан ровно с одной ассоциацией компонента записи. Для агрегата изменения записи каждый component_selector_name каждого component_choice_list должен обозначать отдельный компонент типа агрегата, не являющийся дискриминантом.
Если ассоциация компонента записи с выражением имеет два или более сопоставленных компонента, все они должны иметь один и тот же тип или все они должны быть анонимными типами доступа, подтипы которых статически совпадают. Кроме того, правила допустимости применяются отдельно к каждому сопоставленному компоненту.
Для агрегата записи или агрегата расширения, если часть варианта P вложена в вариант V, который не выбран значением дискриминанта, управляющего частью варианта, содержащей V, то нет ограничений на дискриминант, управляющий P. В противном случае значение дискриминанта, управляющего P, должно быть задано статическим выражением или нестатическим выражением, имеющим ограниченный статический номинальный подтип. В последнем случае нестатического выражения должен быть ровно один список дискретных вариантов P, охватывающий каждое значение, принадлежащее номинальному подтипу и удовлетворяющее предикатам подтипа, и должно быть, по крайней мере, одно такое значение.
Ассоциация компонента записи для дискриминанта без выражения по умолчанию должна содержать выражение, а не <>.
Ассоциация компонента записи в списке ассоциаций компонентов записи агрегата изменения записи не должна:
- Использовать разделитель блока <> вместо выражения;
- Содержать выражение ограниченного типа;
- Опускать component_choice_list; или
- Содержать component_choice_list с выбором others.
Для агрегата изменения записи никакие два component_selector_name не должны обозначать компоненты, объявленные в разных вариантах одной и той же части варианта.
Динамическая семантика
Вычисление агрегата записи состоит из вычисления record_component_association_list.
Для оценки списка_ассоциаций_компонентов_записи, любые ограничения на объект (см. 3.8) для компонентов, указанных в списке ассоциаций, уточняются, и любые выражения вычисляются и преобразуются в подтип связанного компонента. Любые уточнения ограничений и вычисления выражений (и преобразования) происходят в произвольном порядке, за исключением того, что выражение для дискриминанта вычисляется (и преобразуется) до уточнения любых ограничений на объект, зависящих от него, что, в свою очередь, происходит до вычисления и преобразования выражения для компонента с ограничением на объект. Если значение дискриминанта, определяющего выбранную часть_варианта, задано нестатическим выражением, и вычисление этого выражения возвращает значение, которое не принадлежит номинальному подтипу выражения, то генерируется ошибка Constraint_Error.
Для ассоциации_компонентов_записи с выражением, выражение определяет значение для связанного(ых) компонента(ов). Для ассоциации_компонентов_записи со значением <>, если у объявления_компонента есть выражение_по_умолчанию, это выражение_по_умолчанию определяет значение для связанного(ых) компонента(ов); в противном случае, связанные компоненты инициализируются по умолчанию, как для автономного объекта подтипа компонента (см. 3.3.1).
Выражение ассоциации_компонентов_записи вычисляется (и преобразуется) один раз для каждого связанного компонента.
ПРИМЕЧАНИЕ По приведенным выше правилам, для агрегата_записи с позиционными ассоциациями, спецификации_дискриминанта с выражениями, определяющими значения дискриминантов, появляются первыми и в том же порядке, что и соответствующие спецификации_дискриминанта , так как известная_часть_дискриминанта появляется первой в объявлении типа.
Примеры
Пример агрегата записи с позиционными ассоциациями:
(4, Июль, 1776) -- см. 3.8
Примеры агрегатов записей с именованными ассоциациями:
(День => 4, Месяц => Июль, Год => 1776)
(Месяц => Июль, День => 4, Год => 1776)
(Месяц => Июль, День => 4, Год => 1776)
(Диск, Закрыт, Дорожка => 5, Цилиндр => 12) -- см. 3.8.1
(Единица => Диск, Статус => Закрыт, Цилиндр => 9, Дорожка => 1)
(Единица => Диск, Статус => Закрыт, Цилиндр => 9, Дорожка => 1)
Примеры ассоциаций компонентов с несколькими вариантами:
(Значение => 0, Усп|Пред => new Cell'(0, null, null)) -- см. 3.10.1
-- Алокатор вычисляется дважды:
-- Усп и Пред обозначают разные ячейки
-- Усп и Пред обозначают разные ячейки
(Значение => 0, Усп|Пред => <>) -- см. 3.10.1
-- Усп и Пред будут установлены в null
Expression'(null record)
Literal'(Значение => 0.0)
Painted_Point'(0.0, Pi/2.0, Цвет => Красный)
Literal'(Значение => 0.0)
Painted_Point'(0.0, Pi/2.0, Цвет => Красный)