如何为记录类型定义“+”

2 ada

我正在尝试在 ADA 中创建一个包。我有三个文件,adb(主程序)、ads(包)和 adb(主体包)。我看不出我的主文件和包文件有任何问题。但是,在我的 body 包中,我无法编写将 P1 和 P2 的值相加然后返回其值的函数。

我的主程序:

with Ada.Text_IO;                use Ada.Text_IO;
with Ada.Integer_Text_IO;        use Ada.Integer_Text_IO;
with Price_Handling;             use Price_Handling;
procedure Test_Price_Plus is

P1, P2 : Price_Type;  
begin
P1.Dollar:= 19;
P1.Cents:= 50;
P2 := (Dollar => 10, Cents=> 0);
Put("P1 is ");
Put(P1);
New_Line;
Put("P2 is ");
Put(P2); 
New_Line;

Put("If we add P1 and P2, then we get: ");
Put(P1 + P2);
New_Line;
end Test_Price_Plus;
Run Code Online (Sandbox Code Playgroud)

我的包裹:

with Ada.Text_IO;                use Ada.Text_IO;
with Ada.Integer_Text_IO;        use Ada.Integer_Text_IO;
package Price_Handling is

type Price_Type is private;
procedure Get(Item: out Price_Type);
function "+"(Left, Right: in Price_Type) return Price_Type;  -- Left(Dollar), Right(Cents)
private 
type Price_Type is
record
Dollar, Cents: Integer;
end record;
end Price_Handling;
Run Code Online (Sandbox Code Playgroud)

我的包裹体:

Package Body Price_Handling is 
procedure Put(Item:in  Price_Type) is
begin
Put(Item.Dollar); Put(":");
Put(Item.Cents);
end Put; 
function "+"(Left, Right: in Price_Type) return Price_type is   
begin
  -- Need to write a function that adds P1 and P2 together and return its value
  end "+";
Run Code Online (Sandbox Code Playgroud)

Jer*_*ere 5

对于新手来说,最简单的方法可能就是创建一个虚拟的结果值并返回它:

function "+"(Left, Right: in Price_Type) return Price_type is  
   Result : Price_Type; 
begin
   Result.Dollars := Left.Dollars + Right.Dollars;
   Result.Cents   := Left.Cents   + Right.Cents;
   
   -- If your cents are higher than 100, then we 
   -- need to increment dollars and adjust the cents
   -- count
   if Result.Cents > 99 then
      Result.Dollars := Result.Dollars + 1;
      Result.Cents   := Result.Cents - 100;
   end if;

   return Result;
end "+";
Run Code Online (Sandbox Code Playgroud)

然而,这真的很弱。您的 Price_type 不是设计使用可以保护您免受错误的类型。如果您想利用 Ada 的安全方面,请考虑制作一个将您限制为 0 到 99 的 Cents 子类型:

subtype Cents_Type is Natural range 0 .. 99;
Run Code Online (Sandbox Code Playgroud)

这样,如果您犯了一个编程错误并输入了一个大于 99 或负的值,那么程序将捕获它并引发异常。美元也是一样。为非负值创建一个新类型:

subtype Dollars_Type is Natural;
Run Code Online (Sandbox Code Playgroud)

现在更新您的记录以使用这些类型并默认初始化它们:

type Price_Type is record
   Dollars : Dollars_Type := 0;
   Cents   : Cents_Type   := 0;
end record;
Run Code Online (Sandbox Code Playgroud)

然后,如果您这样做,您可以更新 + 函数以使用虚拟变量来保存美分,以防您在将它们加在一起时超过 99。

function "+"(Left, Right: in Price_Type) return Price_type is  
   Result : Price_Type; 
   Cents_With_Overflow : Natural;
begin
   Result.Dollars      := Left.Dollars + Right.Dollars;
   Cents_With_Overflow := Left.Cents + Right.Cents;
   
   -- If your cents are higher than 100, then we 
   -- need to increment dollars and adjust the cents
   -- count
   if Cents_With_Overflow  > 99 then
      Result.Dollars := Result.Dollars + 1;
      Result.Cents   := Cents_With_Overflow - 100;
   else
      Result.Cents   := Cents_With_Overflow;
   end if;

   return Result;
end "+";
Run Code Online (Sandbox Code Playgroud)