Ada - 一维数组操作

Ada - one dimensional array operations

参考 John Barnes 的书“Programming in Ada 2012”(ISBN:978-1-107-42481-4),第 138 页(第 8.6 节)。

procedure ArrayOps is
  type Bit_Row is array (Positive range <>) of Boolean;

  A, B : Bit_Row (1 .. 4);

  T : constant Boolean := True;
  F : constant Boolean := False;
begin
  A := (T, T, F, F);
  B := (T, F, T, F);

  A := A and B;
end ArrayOps;

我在作者提供的最小片段周围添加了一个简单的包装器,这似乎可以按预期进行编译和运行。

作者说这可以用 "Many of the operators" 来完成,这意味着 +*-/ 等算术。

我试图将其转换为使用整数数据类型的加法运算符,但遗憾的是这无法编译...

procedure ArrayOps is
  type Int_Row is array (Positive range <>) of Integer;

  A, B : Int_Row (1 .. 4);

  T : constant Integer := 1;
  F : constant Integer := 0;
begin
  A := (T, T, F, F);
  B := (T, F, T, F);

  A := A + B;
end ArrayOps;

编译器错误状态:arrayops.adb:12:10: there is no applicable operator "+" for type "Int_Row" defined at line 2。这是唯一的错误。显然我的代码中缺少某些东西,但是这本书再也没有提到这个主题。如何为布尔运算符以外的运算符启用数组运算?

编辑:

我已经根据@egilhh 的回答修改了代码,因为这似乎是解决基本问题的最小更改集。

procedure ArrayOps is
  type Int_Row is array (1 .. 4) of Integer;

  function "+"(Left, Right : Int_Row) return Int_Row
  is
     Result : Int_Row;
  begin
     for I in Int_Row'Range loop --'
        Result(I) := Left(I) + Right(I);
     end loop;
     return Result;
  end "+";

  A, B : Int_Row;

  T : constant Integer := 1;
  F : constant Integer := 0;
begin
  A := (T, T, F, F);
  B := (T, F, T, F);

  A := A + B;
end ArrayOps;

现在可以了。但是,我接受了 DeeDee 的回答,因为这可能是最佳实践解决方案。向两位致敬:)

"Many" 并不意味着 "all"... 具体来说,他提到 andorxornot 一个-维度 Boolean 数组。当然,这些只是预定义的;没有什么能阻止您定义自己的运算符。看看第 169 页(第 10.2 节)。

function "+"(Left, Right : Int_Row) return Int_Row
is
   Result : Int_Row;
begin
   for I in Int_Row'Range loop --'
      Result(I) := Left(I) + Right(I);
   end loop;
   return Result;
end "+";

与"many operators"书中提到的逻辑和关系运算符。只有这些运算符是按照语言标准的要求为一维数组类型隐式定义的(请参阅 RM 4.5.1 (2) and RM 4.5.2 (1))。

对于其他运算符,您需要自己实现它们:

arrayops.adb

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO;

procedure ArrayOps is

   type Int_Row is array (Positive range <>) of Integer;

   A, B : Int_Row (1 .. 4);

   T : constant Integer := 1;
   F : constant Integer := 0;

   ---------
   -- "+" --
   ---------

   function "+" (A, B : Int_Row) return Int_Row is     
   begin

      if A'Length /= B'Length then
         raise Constraint_Error with "array lengths do not match";
      end if;

      declare
         Result : Int_Row (1 .. A'Length);
      begin
         for I in Result'Range loop
            Result (I) := A (A'First + I - 1) + B (B'First + I - 1);
         end loop;         
         return Result;
      end;

   end "+";

   ---------
   -- Put --
   ---------

   procedure Put (A : Int_Row; Width : Natural := 0) is      
      use Ada.Integer_Text_IO;
   begin
      for I in A'Range loop
         Put (A (I), Width); 
      end loop;
   end Put;

begin

   A := (T, T, F, F);
   B := (T, F, T, F);

   Put (A, 2); New_Line;
   Put (B, 2); New_Line;

   A := A + B;

   Put ("--------- +"); New_Line;
   Put (A, 2); New_Line;

end ArrayOps;

输出

 1 1 0 0
 1 0 1 0
--------- +
 2 1 1 0