如何在Ada的Predicate_Failure中添加类型相关信息?
在Ada的Predicate_Failure异常中包含类型相关信息
我希望在Predicate_Failure触发的Invalid_Color异常消息中包含类型相关信息,当前可正常运行的代码如下:
subtype Norm is Float range 0.0..1.0; type Component is (Red, Green, Blue, Yellow, White); type Proto_Color is array(Component'Range) of Norm; function Is_Valid(This : Proto_Color) return Boolean is Positive_Count : Natural := 0; Sum : Norm := 0.0; begin for I in Component'Range loop if This(I) > 0.001 then Positive_Count := Positive_Count + 1; Sum := Sum + This(I); end if; end loop; if Positive_Count = 0 or Positive_Count > 2 then return False; end if; if This(Red) > 0.001 and then This(Green) > 0.001 then return False; end if; if This(Yellow) > 0.001 and then This(Blue) > 0.001 then return False; end if; return Sum > 0.999 and then Sum < 1.001; end Is_Valid; Invalid_Color : exception; type Color is new Proto_Color with Dynamic_Predicate => Is_Valid(Proto_Color(Color)), Predicate_Failure => raise Invalid_Color;
注:Proto_Color类型仅用于添加Dynamic_Predicate,我无法在未完成的类型上声明Is_Valid函数。
我尝试通过自定义To_String函数生成包含类型信息的异常消息,但在Predicate_Failure中调用函数时遇到错误,尝试的代码如下:
function To_String(This : Proto_Color) return String is begin return "Red => " & Norm'Image(This(Red)) & ", Green => " & Norm'Image(This(Green)) & ", Blue => " & Norm'Image(This(Blue)) & ", Yellow => " & Norm'Image(This(Yellow)) & ", White => " & Norm'Image(This(White)); end To_String; type Color is new Proto_Color with Dynamic_Predicate => Is_Valid(Proto_Color(Color)), Predicate_Failure => raise Invalid_Color with To_String(Proto_Color'(Color));
遇到的错误
- 保留限定表达式单引号时,错误提示:
期望类型为行[行号]定义的"Proto_Color" 找到类型为行[行号]定义的"Color"
- 去掉限定表达式的单引号后,错误提示变为:
转换的参数不能是聚合类型 请改用限定表达式
解决方案
要解决这个问题,核心是在Predicate_Failure上下文里正确完成类型转换,匹配To_String函数的参数要求。可以采用两种方式调整:
方式一:直接修正类型转换语法
修改Color类型的定义,去掉多余的限定聚合语法,直接使用类型转换:
type Color is new Proto_Color with Dynamic_Predicate => Is_Valid(Proto_Color(Color)), Predicate_Failure => raise Invalid_Color with To_String(Proto_Color(Color));
方式二:扩展To_String函数支持Color类型
新增一个接受Color类型的To_String重载函数,复用原有逻辑:
function To_String(This : Color) return String is begin return To_String(Proto_Color(This)); -- 调用原Proto_Color版本的To_String end To_String; type Color is new Proto_Color with Dynamic_Predicate => Is_Valid(Proto_Color(Color)), Predicate_Failure => raise Invalid_Color with To_String(Color);
原因说明
在Predicate_Failure的上下文里,Color代表当前违反断言的对象,直接通过Proto_Color(Color)即可完成类型转换,无需使用Proto_Color'(Color)这种限定聚合语法——后者适用于聚合值的类型限定,而非对象的类型转换。
内容的提问来源于stack exchange,提问作者Devsman
相关产品推荐
相关产品推荐

