Ада: манипулировать частным типом

Я новичок в Аде и недавно получил ошибку, которую, кажется, не знаю, как решить.

У меня есть следующий код:

данные.объявления

    with Text_IO; use text_io;
with ada.Integer_Text_IO; use ada.Integer_Text_IO;

package data is

type file is private;

   type file_set is array (Integer range <>) of file;
   procedure file_Print (T : in out file); --Not used

private
type file is record
      start, deadline : integer;
end record;

end data;

Main.adb

with ada.Integer_Text_IO; use ada.Integer_Text_IO;


procedure Main is

   Num_files: integer:=3; 
  
   Files:file_set(1..Num_files);
     
begin
   
Files(1):=(2,10); -- Expected private type "file" defined at data.ads

for i in 1..Num_Files loop
      
      Put(integer'Image(i));
      New_Line;
      data.File_Print(Files(i));

Но я получаю эту ошибку Ожидаемый файл частного типа, определенный в data.ads Как я могу получить доступ к типу файла и объявить новый массив значений в main?

Обратите внимание, что «доступ» имеет в Аде особое значение, поэтому его использование в заголовке несколько вводит в заблуждение. "Манипулировать" может быть лучшим выбором.

Jeffrey R. Carter 13.12.2020 10:53
Стоит ли изучать 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
152
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Правильно - вы не можете видеть или манипулировать тем, что находится внутри частного типа. Это было бы нарушением инкапсуляции. Далее следуют ошибки и риски безопасности.

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

Теперь file_set НЕ является закрытым типом (вы можете сделать его закрытым позже, для лучшей инкапсуляции, но сейчас ....), вы можете индексировать его для доступа к файлу внутри него (используя одну из этих процедур).

Files(1):=(2,10);

Поскольку вы хотите создать здесь файл, вам нужен метод для создания файла... немного похожий на конструктор в C++, но на самом деле больше похожий на шаблон проектирования Object Factory. Добавьте это в пакет:

   function new_file(start, deadline : integer) return file;

И реализовать его в теле пакета:

package body data is

    function new_file(start, deadline : integer) return file is
    begin
       -- check these values are valid so we can guarantee a proper file
       -- I have NO idea what start, deadline mean, so write your own checks!
       -- also there are better ways, using preconditions in Ada-2012
       -- without writing explicit checks, but this illustrates the idea
       if deadline < NOW or start < 0 then 
          raise Program_Error;
       end if;
       return (start => start, deadline => deadline);
    end new_file;

    procedure file_Print (T : in out file) is ...

end package body;

и это дает пользователям вашего пакета разрешение писать

Files(1):= new_file(2,10);
Files(2):= new_file(start => 3, deadline => 15);

но если они попытаются создать мусор, чтобы использовать вашу систему

Files(3):= new_file(-99,-10);     -- Oh no you don't!

это ЕДИНСТВЕННЫЙ способ создать файл, поэтому они не смогут обойти ваши проверки.

"это ЕДИНСТВЕННЫЙ способ создать файл": ну нет. «Они» могут сделать F : Data.File;, а затем использовать любые случайные значения, которые он получает по умолчанию. Чтобы избежать этого, вы должны сделать тип неопределенным, но тогда он не может быть компонентом массива; или укажите начальные значения по умолчанию, которые являются недействительными, а затем проверяйте правильность при каждом использовании.

Jeffrey R. Carter 14.12.2020 09:08

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