我有以下一个简单问题:一种表示度数的delta型及其一个子类型,即angles,我将范围限制在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))也不起作用,所以这不是一个优化问题。
我是否错过了理解类型-子类型转换的概念(很可能是这样),并且有人有解决方案/解释吗?甚至是更好的解决方案?
谢谢!
答案 0 :(得分:5)
您的问题与类型转换无关,而与了解类型和子类型之间的区别有关。
类型的所有子类型都具有完全相同的操作。一个类型的子类型之间的差异(包括类型本身,从技术上讲就是“该类型的第一个子类型”)只是允许值的集合。
这意味着您在Degrees
和Limited_Degrees
之间进行的所有转换都做不了多少,而您对Units.Base.Degrees."+" (Left, Right)
的调用实际上是递归调用。
我认为解决您的问题的方法是使Limited_Degrees
成为派生类型,而不是子类型。
答案 1 :(得分:0)
目前没有可用的编译器,因此未经测试,但
res := Units.Base.Degrees."+"(Left, Right);
令人怀疑,因为您不需要为"+"
和left
指定right
和Limited_Angle
的运算符"+"
。所以我想知道上面的行是否正在调用当前的function "+" (Left, Right : in Degree) return Limited_Angle
运算符(因此是递归的)?
我会看看是否写:
"+"
是更好的选择,因为您可以在对Degree
取模之前在Limited_Angle
中进行Drop Table #MyTempTable
Create Table #MyTempTable (
NAME NVARCHAR(100)
);
Insert Into #MyTempTable VALUES ('3243')
Insert Into #MyTempTable VALUES ('123')
Insert Into #MyTempTable VALUES ('432423')
Insert Into #MyTempTable VALUES ('423')
Insert Into #MyTempTable VALUES ('432')
select * from #MyTempTable
Update #MyTempTable
SET NAME = 'A' + REPLICATE('*', len(NAME) - 1)
select * from #MyTempTable
的数学运算。这也将保存您的演员表。