Ada:子类型转换或调用“Base”
Ada: Subtype Conversion or calling 'Base
我有以下 - 简单 - 问题:表示度数的增量类型及其子类型,角度,我将范围限制在 0.0 .. <360.0 之间。
现在,我想覆盖子类型的“+”运算符以拥有我自己的模运算符:
package ...
type Degree is digits Degree_Digits;
end package
package ...
subtype Limited_Angle is Degree range Degree_Min .. Degree_Max;
function "+" (Left, Right : in Limited_Angle) return Limited_Angle;
end package
和实施:
function "+" (Left, Right : in Limited_Angle) return Limited_Angle is
res : Degree;
begin
res := Units.Base.Degrees."+"(Left, Right);
...
return Limited_Angle(res);
end "+";
但我不喜欢调用 +-运算符的方式。我的第一个想法是
res := Degree(Left) + Degree(Right);
但这不起作用。我的编译器警告无限递归。
甚至更严格:
res := (Degree(Left)) + (Degree(Right));
警告无限递归。我不明白这背后的原理。 T(S) 不应该将 S 转换为 T 吗?它不可能是优化问题,因为 (T(S)) 也不起作用。
我是否误解了类型-子类型转换的概念(很可能),有人有 solution/explanation 吗?或者更好的解决方案?
谢谢!
目前没有可用的编译器,因此未测试,但是
res := Units.Base.Degrees."+"(Left, Right);
是可疑的,因为您不需要为 left
和 right
指定运算符 "+"
,它们是 Limited_Angle
。所以我想知道上面的行是否正在调用当前的 "+"
运算符(因此是递归的)?
我会看看是否写:
function "+" (Left, Right : in Degree) return Limited_Angle
是一个更好的选择,因为您可以在对 Limited_Angle
取模之前在 Degree
中进行 "+"
数学计算。这也将节省您随叫随到的演员阵容。
您的问题与类型转换无关,而是与理解类型和子类型之间的区别有关。
一个类型的所有子类型都具有完全相同的操作。类型的子类型(包括类型本身,技术上 "first subtype of the type")之间的差异只是允许值的集合。
这意味着你在 Degrees
和 Limited_Degrees
之间的所有转换都没有做太多,你对 Units.Base.Degrees."+" (Left, Right)
的调用实际上是一个递归调用。
我认为您的问题的解决方案是使 Limited_Degrees
成为派生类型,而不是子类型。
我有以下 - 简单 - 问题:表示度数的增量类型及其子类型,角度,我将范围限制在 0.0 .. <360.0 之间。 现在,我想覆盖子类型的“+”运算符以拥有我自己的模运算符:
package ...
type Degree is digits Degree_Digits;
end package
package ...
subtype Limited_Angle is Degree range Degree_Min .. Degree_Max;
function "+" (Left, Right : in Limited_Angle) return Limited_Angle;
end package
和实施:
function "+" (Left, Right : in Limited_Angle) return Limited_Angle is
res : Degree;
begin
res := Units.Base.Degrees."+"(Left, Right);
...
return Limited_Angle(res);
end "+";
但我不喜欢调用 +-运算符的方式。我的第一个想法是
res := Degree(Left) + Degree(Right);
但这不起作用。我的编译器警告无限递归。 甚至更严格:
res := (Degree(Left)) + (Degree(Right));
警告无限递归。我不明白这背后的原理。 T(S) 不应该将 S 转换为 T 吗?它不可能是优化问题,因为 (T(S)) 也不起作用。
我是否误解了类型-子类型转换的概念(很可能),有人有 solution/explanation 吗?或者更好的解决方案?
谢谢!
目前没有可用的编译器,因此未测试,但是
res := Units.Base.Degrees."+"(Left, Right);
是可疑的,因为您不需要为 left
和 right
指定运算符 "+"
,它们是 Limited_Angle
。所以我想知道上面的行是否正在调用当前的 "+"
运算符(因此是递归的)?
我会看看是否写:
function "+" (Left, Right : in Degree) return Limited_Angle
是一个更好的选择,因为您可以在对 Limited_Angle
取模之前在 Degree
中进行 "+"
数学计算。这也将节省您随叫随到的演员阵容。
您的问题与类型转换无关,而是与理解类型和子类型之间的区别有关。
一个类型的所有子类型都具有完全相同的操作。类型的子类型(包括类型本身,技术上 "first subtype of the type")之间的差异只是允许值的集合。
这意味着你在 Degrees
和 Limited_Degrees
之间的所有转换都没有做太多,你对 Units.Base.Degrees."+" (Left, Right)
的调用实际上是一个递归调用。
我认为您的问题的解决方案是使 Limited_Degrees
成为派生类型,而不是子类型。