在this question中,我问如何定义一个范围的无限上限(事实证明答案是相当明显的,但对于Ada的新人却没有)。在答案中,建议为此创建特定子类型。
问题中提到的某种特定子类型如下所示:
Type Speed is Float range 0 .. Float'Last
此外,我注意到此Ada项目中的很大一部分代码具有特定类型 - 如Feet_Float
和Meters_Float
等。为什么这是首选实践,而不是仅仅在类/包中的基本float
成员变量上设置范围约束?
答案 0 :(得分:8)
Ada不喜欢亚型 - Ada程序员这样做。
新类型和子类型(它们不同,两者都有它们的用途)有助于在如此少的成本或时间损失下捕获如此多的错误,这是一个谜,为什么良好的类型系统到目前为止已经过时了。
例如,要认识到任何数组的索引都属于一个子类型(可能是匿名的,但可以像myArray'range
或for i in myArray'range loop ... end loop;
一样subtype myIndextype is myArray'range; theIndex : myIndextype;
访问,并且您会看到每个缓冲区溢出漏洞 - 或者攻击 - 只是一个类型错误 - 或者本来就是Ada。
当你遇到编译器的错误时,第一次执行可执行文件时,Exception : Constraint_Error
指向错误地接近错误,你就会开始了解范围限制的值类型。
为了进一步扩展这一点,我将引用更多Q& As。
首先请注意,您可能使用的编译器Gnat可能不是严格遵守Ada,除非您在命令行(或项目文件)中添加了几个可选标志,如第一个示例中所述。最近的版本默认启用了其中一些版本。
这里是subtype being declared, used and going out of visible scope,的示例(在declare
块中,其中子类型的范围在运行时之前是未知的。与许多动态类型语言不同,这既快速又安全,因为相关存储通常在堆栈中,如果您对实现细节感兴趣。
how not to use a declare block.
的一个例子这是not only declaring subtypes but telling the compiler how to pack them in storage的一个极端例子。嵌入式编程中常见的,无论是空间紧张(我在具有1kbyte内存的处理器中都有完整的数字手表!)或者用于访问硬件寄存器中的特定位。 (请注意,如果更新为使用Ada-2012 aspects
,则此示例会更干净。)
对于来自Java的人来说,这个Q& A简要介绍了difference between new types and subtypes。 (我有点失望,没有一位Java专家在关闭之前就回答了这个问题,并描述了他们如何处理相同的问题)
答案 1 :(得分:5)
Ada的范例是对解决方案中的问题进行建模。其中一个方面是使用适当的标量类型和子类型定义对问题空间中值的范围,精度和精度进行建模。
为什么要这样做? McCormick在分析为什么具有C经验且没有Ada经验的学生能够在Ada完成他的实时S / W课程项目但在C中没有完成时发现Ada最重要的特征是
标量对象的建模。
- 强力打字。
- 范围限制。
- 枚举类型。
答案 2 :(得分:4)
特定类型的声明具有以下好处: