You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

有限类型的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 18:35:14