在 Ada 中隐藏运算符,同时仍在包体中使用它

Hiding an operator in Ada while still using it in the package body

我需要有关在 Ada 中隐藏运算符的指导,同时仍然从声明类型的包体中调用它。

我在包中有一个类型,其中一些内部运算符通过将运算符定义标记为抽象来隐藏,因为从语义上讲这是无意义的。但是我仍然需要主体中的运算符,以便可以比它们的变通方法更有效地计算其他操作。有没有办法将运算符标记为在体内不是抽象的,即使它在规范中是抽象的?或者我需要声明一个新的等效函数并从 Intrinsics 导入吗?

有问题的运算符是 */

我不相信你可以"mark the operator as not abstract within the body"。

重新导入内在函数的一种相当简洁的方法是

package Abstracting is
   type T is new Integer;
   function "+" (L, R : T) return T is abstract;
   function Add (L, R : T) return T;
end Abstracting;

(我在猜测你的实际类型——它必须是明显的数字,否则 "+""/" 一开始就不是问题)。

然后,

package body Abstracting is

   package Intrinsics is
      function "+" (L, R : T) return T with Import, Convention => Intrinsic;
   end Intrinsics;

好的,重新导入 "+"。现在使其可见:

   use Intrinsics;

   function Add (L, R : T) return T is
   begin
      return L + R;

使用包 Intrinsics 中的 "+" 版本(我尝试将 use 放在 Add 中,但它没有用。必须非常接近边缘在这里:)

   end Add;
end Abstracting;

通常将 public 定义设为私有,并且只声明对抽象有意义的操作。这使得主体中可用的完整类型的未定义但固有的操作:

package P is
   type T is private;
   function "+" (Left : T; Right : T) return T;
   function "-" (Left : T; Right : T) return T;
private -- P
   type T is range ...;
end P;

这种方法的难点不在于使用未定义的操作,而在于当您需要使用已覆盖的内部操作时:在本例中为“+”和“-”。这通常通过派生 T、将值转换为父类型以执行操作并转换回 T:

来解决
private -- P
   type Raw is range ...;
   type T is new Raw;
end P;

然后pkg body中的Raw可以使用"+"和"-":

function "+" (Left : T; Right : T) return T is
   (T (Raw (Left) + Raw (Right) ) );