有限类型的Ada扩展聚合为何出现语法错误?
Ada带判别式标记类型的子类构造问题
你的注释代码里的uncle_type实现存在几个语法和逻辑错误,导致编译失败:
overriding关键字误用:父包p2里的create_child不是标记类型的primitive操作(它的参数列表里没有child_type类型的对象),所以子类不能用overriding修饰这个函数。- 聚合初始化语法错误:当用
(父类实例 with ...)的方式扩展聚合时,不能重新指定父类的判别式(比如cs => 2)——父类实例的判别式已经确定,子类继承的判别式必须和父类保持一致,不能在扩展时修改。 - 判别式不匹配:你构造时传入父类实例的cs是4,但子类指定的cs是2,两者类型判别式不匹配,必然触发类型错误。
两种正确的构造方式
下面是修复后的uncle_type实现,包含两种合法的构造方式:
方式一:直接扩展基类的聚合初始化
这种方式和p2里初始化c常量的逻辑一致,直接从最基础的base_type开始扩展,明确指定所有必要的字段和判别式:
package p3 is type uncle_type (cs : natural) is new p2.child_type (cs) with record f3 : character; end record; -- 注意:不要加overriding,因为父类的create_child不是primitive操作 function create_child ( cs : natural; f2 : boolean; f3 : character := 'x' -- 可选参数,默认值 ) return uncle_type; procedure print (gc : in uncle_type); end p3; package body p3 is function create_child ( cs : natural; f2 : boolean; f3 : character := 'x' ) return uncle_type is begin -- 直接从base_type扩展,保证判别式cs一致 return (p1.base_type with cs => cs, f2 => f2, f3 => f3); end create_child; procedure print (gc : in uncle_type) is begin put_line ("parent: " & p2.child_type (gc).image & " cs: " & gc.cs'img & " f3: " & gc.f3'img); end print; end p3;
方式二:基于父类实例扩展聚合
如果需要复用父类的构造函数p2.create_child,可以先创建父类实例(保证判别式和子类一致),再扩展子类的额外字段:
package body p3 is function create_child ( cs : natural; f2 : boolean; f3 : character := 'x' ) return uncle_type is -- 先创建父类实例,cs必须和子类参数一致 Parent_Obj : constant p2.child_type := p2.create_child(cs, f2); begin -- 基于父类实例扩展,只需要指定子类新增的字段 return (Parent_Obj with f3 => f3); end create_child; -- print过程和方式一一致 procedure print (gc : in uncle_type) is begin put_line ("parent: " & p2.child_type (gc).image & " cs: " & gc.cs'img & " f3: " & gc.f3'img); end print; end p3;
验证使用
在主程序里可以这样调用测试:
u : constant p3.uncle_type := p3.create_child(3, true, 'b'); begin -- ... 原有代码 ... u.print; end Example;
这样就能正确编译并输出预期结果,同时避免了之前的语法错误。
内容的提问来源于stack exchange,提问作者Wayne
相关产品推荐
相关产品推荐

