Можно ли объявить общую функцию как для ограниченных, так и для неограниченных массивов?

Скажем, у меня есть формальный тип массива и функция для поиска индекса данного элемента в этом массиве, например:

generic
   type T is private;
   type T_index is (<>);
   type T_array is array(T_index range <>) of T;
function FindIndexGeneric(array: T_array; element: T; elementFound: out Boolean) return T_index;

Создание экземпляра для неограниченного массива, такого как строка, отлично работает:

function FindIndexString is new FindIndexGeneric
  (T=>Character, T_index=>Positive, T_array=>String);

Но то же самое не работает, когда у меня есть ограниченный массив:

type userIDIndex is Integer range 1..6;
type userID is array(userIDIndex) of Character;
function FindIndexUserID is new FindIndexGeneric
  (T=>Character, T_index=>userIDIndex, T_array=>userID);
-- error: expect unconstrained array in instantiation of "T_array"

Я могу заставить массивы с ограничениями работать, изменив строку объявления формального массива на:

type T_array is array(T_index) of T;

но тогда я не могу создавать неограниченные массивы с этим.

Учитывая, что основная логика в моих функциях массива (FindIndexGeneric) одинакова, я не хочу создавать несколько ее версий, по одной для массивов с ограничениями и без ограничений.

Есть ли способ заставить общую функцию работать как с ограниченными, так и с неограниченными массивами?

Ваша логика идет в ограниченном варианте. Неограниченная версия объявляет соответствующий ограниченный подтип, создает с ним экземпляр ограниченной версии и вызывает ограниченный экземпляр.

Jeffrey R. Carter 11.01.2023 11:35
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не думаю, что есть способ создать универсальный экземпляр как с ограниченным, так и с неограниченным массивом, но есть своего рода обходной путь: вы можете создать экземпляр с неограниченным массивом и определить ограниченный подтип неограниченного типа массива, и затем вы можете вызвать созданную универсальную функцию с параметром ограниченного подтипа. Так:

generic
   type T is private;
   type T_index is (<>);
   type T_array is array (T_index range <>) of T;
...
type userIDIndex is Integer range 1..6;
type userIDUnconstrained is
   array (userIDIndex range <>) of Character;
subtype userID is userIDUnconstrained (userIDIndex);

function FindIndexUserID is new FindIndexGeneric
  (T       => Character,
   T_index => userIDIndex,
   T_array => userIDUnconstrained);

Затем вы можете вызвать FindIndexUserID с параметром ограниченного (под)типа userID. Однако обратите внимание, что в теле дженерика вы должны пройти по параметру массива, перебирая диапазон его индексов (arry'Range), а не весь T_index.

Другие вопросы по теме