Когда вы указываете, что универсальный параметр является закрытым типом, Ада предполагает, что вы это имеете в виду: -)
т.е. у вас нет доступа к его компонентам. Ада не является " типом утки ", поэтому не имеет значения, знаете ли вы, что экземплярный тип может действительно обладать определенным полем. (Как вы ожидаете, что ваша функция Checksum будет работать, если параметр The_Transfer_Type был создан, например, с помощью Integer?)
Одним из способов решения этой проблемы является также предоставление функции доступа в качестве параметра для универсального объекта, который будет извлекать данные, необходимые, в данном случае, для вычисления контрольной суммы. E.g.:
generic
type The_Transfer_Type is private;
with function Get_Checksummable_Data_Item
(Msg : The_Transfer_Type;
I : Integer) return Integer;
SIZE : Integer;
package CC_Test_Channel is
function Checksum(Msg : The_Transfer_Type) return Integer;
end CC_Test_Channel;
Тело тогда:
function Checksum(Msg : The_Transfer_Type) return Integer is
Sum : Integer := 0;
begin
-- calculate the checksum
for i in 1 .. SIZE loop
Sum := Sum + Get_Checksummable_Data(Msg, I);
end loop;
return Sum;
end Checksum;
Функция, которую вы предоставляете для Get_Checksummable_Data, затем относится к The_Transfer_Type и просто возвращает выбранное значение из полей компонента The_Transfer_Type.
Существует также ряд других способов установить это, например, предоставление неограниченного типа массива в качестве общего формального параметра и формальной функции для его получения - это позволяет вам также избавиться от явного формального параметра SIZE , Или вы можете написать функцию Checksum () как одну из операций над типом, с которым вы создаете экземпляр CC_Test_Channel, и затем иметь:
with function Calculate_Checksum(Msg : The_Transfer_Type) return Integer;
как один из общих формалей.
Сделай шаг назад и подумай о возможностях ...