Ada实现输入掩码:依托类型系统控制输入并捕获异常
实现Ada类型驱动的输入掩码方案
原代码编译失败的核心原因是标准库Ada.Text_IO.Get_Line没有针对自定义record类型的重载,直接传入record参数不符合接口要求。如果要依托Ada原生类型机制、异常捕获实现输入管控,不需要手动拼接字符串做硬判断,可以通过类型重载+子类型约束的方式实现,所有校验逻辑由语言本身完成。
核心实现逻辑
- 将掩码每个位置的取值范围定义为独立的字符子类型,把规则直接绑定到类型上,而非写在record字段声明里
- 为自定义掩码record类型重载
Get过程,逐位读取输入字符,赋值给对应字段时,Ada运行时会自动校验值是否符合子类型的范围约束,不符合时直接抛出Constraint_Error异常,不需要手动写范围判断代码 - 在异常块中统一捕获输入长度不足、取值不符合范围等错误,返回对应提示即可
可直接运行的示例代码
-- Date: 11/06/2022 with Ada.Text_IO; Use Ada.Text_IO; with Ada.Characters.Latin_1; procedure Masques is -- 按掩码规则定义带范围约束的子类型 subtype Seg1 is Character range 'A'..'D'; subtype Seg2 is Character range 'E'..'H'; subtype Seg3 is Character range 'I'..'L'; type Masked_Input is record X1 : Seg1; X2 : Seg2; X3 : Seg3; end record; -- 为掩码类型重载Get方法 procedure Get (Item : out Masked_Input) is Temp_Char : Character; Has_Input : Boolean; begin -- 跳过前置换行符,避免读取到上一次输入残留的行尾符 loop Look_Ahead(Temp_Char, Has_Input); exit when not Has_Input or else Temp_Char /= Ada.Characters.Latin_1.LF; Get(Temp_Char); end loop; -- 逐位读取输入,赋值时自动触发类型范围校验 Get(Item.X1); Get(Item.X2); Get(Item.X3); end Get; Input_Result : Masked_Input; begin Put("请输入3位字符(第1位A-D,第2位E-H,第3位I-L):"); Get(Input_Result); New_Line; Put_Line("输入校验通过,内容:" & Input_Result.X1 & Input_Result.X2 & Input_Result.X3); exception when Constraint_Error => New_Line; Put_Line("输入错误:存在字符不符合对应位置的取值范围要求"); when End_Error => New_Line; Put_Line("输入错误:输入长度不足3位,请补充完整内容"); end Masques;
扩展说明
- 如果需要调整掩码规则,只需要修改对应子类型的范围定义、增减record字段即可,核心输入读取逻辑不需要改动
- 如果需要支持带固定分隔符的掩码格式(比如身份证号、手机号格式的固定分隔位),只需要在重载的
Get过程中增加分隔符读取逻辑,若读取到的分隔符不符合预期,手动触发Constraint_Error即可统一纳入异常处理流程 - 该方案完全依托Ada原生的类型安全机制实现,没有额外的硬编码校验逻辑,输入管控逻辑和类型定义绑定,后续维护成本极低
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

