Я новичок в Аде и недавно получил ошибку, которую, кажется, не знаю, как решить.
У меня есть следующий код:
данные.объявления
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?
Правильно - вы не можете видеть или манипулировать тем, что находится внутри частного типа. Это было бы нарушением инкапсуляции. Далее следуют ошибки и риски безопасности.
Вы можете взаимодействовать с закрытым типом только через его методы: функции и процедуры, объявленные в пакете, где он объявлен.
Теперь 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;
, а затем использовать любые случайные значения, которые он получает по умолчанию. Чтобы избежать этого, вы должны сделать тип неопределенным, но тогда он не может быть компонентом массива; или укажите начальные значения по умолчанию, которые являются недействительными, а затем проверяйте правильность при каждом использовании.
Обратите внимание, что «доступ» имеет в Аде особое значение, поэтому его использование в заголовке несколько вводит в заблуждение. "Манипулировать" может быть лучшим выбором.