在 Ada 中隐藏某些运算符
Hiding certain operators in Ada
假设我有以下类型:
type Example_Type is new Float;
将为Example_Type定义大量的内在运算符,这在绝大多数情况下都是好的。喜欢:
function "+"(Left, Right : Example_Type) return Example_Type;
和
function "*"(Left, Right : Example_Type) return Example_Type;
但是假设两个 Example_Type 的乘积不应该等于另一个 Example_Type,就像 Dimensions 中发生的那样。如何有选择地隐藏这些内部运算符?
您将不允许的操作抽象化:
procedure Disallow is
type Length is digits 10;
function "*" (Left, Right : Length) return Length is abstract;
A, B, C, D : Length := 2.0;
begin
C := A + B;
D := A * C; -- Compiler will complain here.
end Disallow;
您必须定义一个产生所需类型结果的重载函数。虽然有时需要禁用内部运算符定义,但并非必须这样做才能获得所需的运算符定义。
type Example_Type is new float;
type Other_Type is new float;
function "*" (Left, Right : Example_Type) return Other_Type;
Ada 可以根据函数的 return 类型解决重载问题。
您可以将它们重写为抽象的,但我认为这是错误的做法。与其试图摆脱操作,不如将类型声明为仅具有所需的操作:
type Example is private;
function "+" (Left : Example; Right : Example) return Example;
-- "*" not defined
对于其他类型为数字的类型,问题在于您不能将数字文字与该类型一起使用。这可以通过
之类的东西有所缓解
function "+" (Right : Integer) return Example;
所以你写 +42
而不是 42
,这还不算太糟糕,尽管在二元运算符的情况下它仍然很尴尬:X / (+42)
.
假设我有以下类型:
type Example_Type is new Float;
将为Example_Type定义大量的内在运算符,这在绝大多数情况下都是好的。喜欢:
function "+"(Left, Right : Example_Type) return Example_Type;
和
function "*"(Left, Right : Example_Type) return Example_Type;
但是假设两个 Example_Type 的乘积不应该等于另一个 Example_Type,就像 Dimensions 中发生的那样。如何有选择地隐藏这些内部运算符?
您将不允许的操作抽象化:
procedure Disallow is
type Length is digits 10;
function "*" (Left, Right : Length) return Length is abstract;
A, B, C, D : Length := 2.0;
begin
C := A + B;
D := A * C; -- Compiler will complain here.
end Disallow;
您必须定义一个产生所需类型结果的重载函数。虽然有时需要禁用内部运算符定义,但并非必须这样做才能获得所需的运算符定义。
type Example_Type is new float;
type Other_Type is new float;
function "*" (Left, Right : Example_Type) return Other_Type;
Ada 可以根据函数的 return 类型解决重载问题。
您可以将它们重写为抽象的,但我认为这是错误的做法。与其试图摆脱操作,不如将类型声明为仅具有所需的操作:
type Example is private;
function "+" (Left : Example; Right : Example) return Example;
-- "*" not defined
对于其他类型为数字的类型,问题在于您不能将数字文字与该类型一起使用。这可以通过
之类的东西有所缓解function "+" (Right : Integer) return Example;
所以你写 +42
而不是 42
,这还不算太糟糕,尽管在二元运算符的情况下它仍然很尴尬:X / (+42)
.