如何执行安全类型转换检查?
How do you perform a check for safe type conversion?
前言:我正在使用 GNAT 社区使用最新版本的 SPARK Ada 进行编程(截至撰写时)。
我一直在互联网上寻找一个简单的解决方案,但所有结果似乎都指向同一个答案,但对我不起作用。我有一个新类型 Digit
定义为 TYPE Digit IS new Integer range 0 .. 9
。我想安全地将 Integer
转换为 Digit
。为了进行此转换,我还创建了一个范围 DigitRange
,定义为 TYPE DigitRange IS range 0 .. 9
。我试图通过检查 Digit
是否在范围内 (IF InputInteger IN DigitRange
) 来执行此转换,但这会引发 不兼容类型 编译错误。
- 是否可以引用定义
Digit
类型的范围0 .. 9
而不具体说明IF InputInteger IN Digit
?因为没有子类型,IN
不会产生有用的结果,并且 if 语句将无效。我想在代码中明确写入,我的转换不是通过检查与任意变量(例如 DigitRange
. 的兼容性来执行的
- 是否可以在不进行子类型化的情况下完全执行此类型转换,同时保持安全并且不接收 范围检查可能会失败 来自
gnatprove
的错误?
- 或者,我是否应该一开始不执行检查,转换类型然后执行
Output'Valid
作为最后的手段?据我了解,对于类型转换本身,这仍然会给我一个 范围检查可能会失败 。
我知道实现此目的的更理想解决方案是使用子类型,但我不允许这样做。
感谢您的回答。
将 Integer'Pos 应用于 Integer 值会将其“转换”为“通用整数”,然后您可以测试它是否包含在任何整数类型的范围内:
X : Integer;
...
if Integer'Pos(X) in Digit then ...
与 Ada 中的许多事情一样,在 Ada 中有多种方法可以做到这一点,虽然使用 'Pos
是一个很好的解决方案,但看看其他一些可能会有用。
由于Digit
派生自Integer
,它们的基类型范围相同,所以可以写成
Digit'Base (X) in Digit
您还可以定义具有所需范围的 Integer 子类型并将其用于比较
subtype Digit_Range is Integer range Digit'First .. Digit'Last;
X in Digit_Range
[not] in
右边也可以是子类型定义,所以也可以用
X in Integer range Digit'First .. Digit'Last
前言:我正在使用 GNAT 社区使用最新版本的 SPARK Ada 进行编程(截至撰写时)。
我一直在互联网上寻找一个简单的解决方案,但所有结果似乎都指向同一个答案,但对我不起作用。我有一个新类型 Digit
定义为 TYPE Digit IS new Integer range 0 .. 9
。我想安全地将 Integer
转换为 Digit
。为了进行此转换,我还创建了一个范围 DigitRange
,定义为 TYPE DigitRange IS range 0 .. 9
。我试图通过检查 Digit
是否在范围内 (IF InputInteger IN DigitRange
) 来执行此转换,但这会引发 不兼容类型 编译错误。
- 是否可以引用定义
Digit
类型的范围0 .. 9
而不具体说明IF InputInteger IN Digit
?因为没有子类型,IN
不会产生有用的结果,并且 if 语句将无效。我想在代码中明确写入,我的转换不是通过检查与任意变量(例如DigitRange
. 的兼容性来执行的
- 是否可以在不进行子类型化的情况下完全执行此类型转换,同时保持安全并且不接收 范围检查可能会失败 来自
gnatprove
的错误? - 或者,我是否应该一开始不执行检查,转换类型然后执行
Output'Valid
作为最后的手段?据我了解,对于类型转换本身,这仍然会给我一个 范围检查可能会失败 。
我知道实现此目的的更理想解决方案是使用子类型,但我不允许这样做。
感谢您的回答。
将 Integer'Pos 应用于 Integer 值会将其“转换”为“通用整数”,然后您可以测试它是否包含在任何整数类型的范围内:
X : Integer;
...
if Integer'Pos(X) in Digit then ...
与 Ada 中的许多事情一样,在 Ada 中有多种方法可以做到这一点,虽然使用 'Pos
是一个很好的解决方案,但看看其他一些可能会有用。
由于Digit
派生自Integer
,它们的基类型范围相同,所以可以写成
Digit'Base (X) in Digit
您还可以定义具有所需范围的 Integer 子类型并将其用于比较
subtype Digit_Range is Integer range Digit'First .. Digit'Last;
X in Digit_Range
[not] in
右边也可以是子类型定义,所以也可以用
X in Integer range Digit'First .. Digit'Last