Руководство по Ada (Ada 2022)
4.1.3 Выбранные компоненты
Selected_component используются для обозначения компонентов (включая дискриминанты), входов, семейств входов и защищенных подпрограмм; они также используются в качестве расширенных имён, как описано ниже.
Синтаксис
Правила разрешения имён
selected_component называется расширенным именем, если, согласно правилам видимости, по крайней мере одно возможное толкование его prefix обозначает пакет или содержащую именованную конструкцию (непосредственно, а не через subprogram_renaming_declaration или generic_renaming_declaration).
selected_component, который не является расширенным именем, должен разрешаться, обозначая один из следующих пунктов:
- Компонент (включая дискриминант):
prefix должен разрешаться, обозначая объект или значение некоторого не массивно-составного типа (после любого неявного разыменования). selector_name должен разрешаться, обозначая discriminant_specification типа или, если тип не является защищённым типом, component_declaration типа. selected_component обозначает соответствующий компонент объекта или значения.
- Один вход, семейство входов или защищённая подпрограмма:
prefix должен разрешаться, обозначая объект или значение некоторого типа задачи или защищённого типа (после любого неявного разыменования). selector_name должен разрешаться, обозначая entry_declaration или subprogram_declaration, встречающиеся (неявно или явно) внутри видимой части этого типа. selected_component обозначает соответствующий вход, семейство входов или защищённую подпрограмму.
- Вид подпрограммы, первый формальный параметр которой является типа с меткой или параметром доступа, обозначенный тип которого имеет метку:
prefix (после любого неявного разыменования) должен разрешаться, обозначая объект или значение конкретного типа с меткой T или типа всего класса T'Class. selector_name должен разрешаться, обозначая вид подпрограммы, объявленной непосредственно внутри области объявления, в которой объявлен предок типа T. Первый формальный параметр подпрограммы должен быть типа T или типа всего класса, охватывающего T, или параметром доступа, обозначающим один из этих типов. Обозначение подпрограммы не должно совпадать с обозначением компонента типа с меткой, видимого в момент selected_component. Подпрограмма не должна быть неявно объявленной примитивной операцией типа T, которая переопределяет унаследованную подпрограмму, реализованную входом или защищённой подпрограммой, видимой в момент selected_component. selected_component обозначает вид этой подпрограммы, исключающий первый формальный параметр. Этот вид называется префиксным видом подпрограммы, а prefix selected_component (после любого неявного разыменования) называется префиксом префиксного вида.
Расширенное имя должно разрешаться, обозначая объявление, которое происходит непосредственно внутри именованной области объявления, следующим образом:
- prefix должен разрешаться, обозначая либо пакет (включая текущий экземпляр обобщённого пакета или переименование пакета), либо содержащую именованную конструкцию.
- selector_name должен разрешаться, обозначая объявление, которое происходит непосредственно внутри области объявления пакета или содержащей конструкции (объявление должно быть видимым в месте расширенного имени — см. 8.3). Расширенное имя обозначает это объявление.
- Если prefix не обозначает пакет, то он должен быть direct_name или расширенным именем, и он должен разрешаться, обозначая единицу программы (кроме пакета), текущий экземпляр типа, block_statement, loop_statement или accept_statement (в случае accept_statement или entry_body индекс семейства не допускается); расширенное имя должно находиться в области объявления данной конструкции. Кроме того, если эта конструкция является вызываемой конструкцией, и prefix обозначает более одной такой содержащей вызываемой конструкции, то расширенное имя является неоднозначным, независимо от selector_name.
Правила легальности
Для префиксного вида подпрограммы, первый формальный параметр которой является параметром доступа, префикс должен быть легальным в качестве prefix attribute_reference с attribute_designator Access, появляющимся в качестве первого фактического параметра в вызове подпрограммы без префикса.
Для подпрограммы, первый параметр которой имеет режим in out или out, или анонимного типа доступа к переменной, префикс любого префиксного вида должен обозначать переменную.
Динамическая семантика
Вычисление selected_component включает вычисление prefix.
Для selected_component, обозначающего компонент variant, выполняется проверка, что значения дискриминантов таковы, что значение или объект, обозначенный prefix, имеет этот компонент. Исключение Constraint_Error возбуждается, если эта проверка терпит неудачу.
Примеры
Примеры выбранных компонентов:
Tomorrow.Month -- компонент записи (см. 3.8)
Next_Car.Owner -- компонент записи (см. 3.10.1)
Next_Car.Owner.Age -- компонент записи (см. 3.10.1)
-- предыдущие две строки включают неявное разыменование
Writer.Unit -- компонент записи (дискриминант) (см. 3.8.1)
Min_Cell(H).Value -- компонент записи результата (см. 6.1)
-- вызова функции Min_Cell(H)
Cashier.Append -- префиксный вид процедуры (см. 3.9.4)
Control.Seize -- вход защищённого объекта (см. 9.4)
Pool(K).Write -- вход задачи Pool(K) (см. 9.1)
Next_Car.Owner -- компонент записи (см. 3.10.1)
Next_Car.Owner.Age -- компонент записи (см. 3.10.1)
-- предыдущие две строки включают неявное разыменование
Writer.Unit -- компонент записи (дискриминант) (см. 3.8.1)
Min_Cell(H).Value -- компонент записи результата (см. 6.1)
-- вызова функции Min_Cell(H)
Cashier.Append -- префиксный вид процедуры (см. 3.9.4)
Control.Seize -- вход защищённого объекта (см. 9.4)
Pool(K).Write -- вход задачи Pool(K) (см. 9.1)
Примеры расширенных имён:
Key_Manager."<" -- оператор видимой части пакета (см. 7.3.1)
Dot_Product.Sum -- переменная, объявленная в теле функции (см. 6.1)
Buffer.Pool -- переменная, объявленная в защищённом блоке (см. 9.11)
Buffer.Read -- вход защищённого блока (см. 9.11)
Swap.Temp -- переменная, объявленная в блочном операторе (см. 5.6)
Standard.Boolean -- имя предопределённого типа (см. A.1)
Dot_Product.Sum -- переменная, объявленная в теле функции (см. 6.1)
Buffer.Pool -- переменная, объявленная в защищённом блоке (см. 9.11)
Buffer.Read -- вход защищённого блока (см. 9.11)
Swap.Temp -- переменная, объявленная в блочном операторе (см. 5.6)
Standard.Boolean -- имя предопределённого типа (см. A.1)