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

Ada2012继承判别式使用报错咨询及替代写法合规性疑问

Ada 2012 代码问题解析

原始代码与报错

原始代码:

procedure Main is
  
  type Component_t (Id : Natural) is tagged limited null record;
  
  type Root_t (Id : Natural) is tagged limited null record;
  
  type Child_t is limited new Root_t with
     record
       component : Component_t(Id => Id);
     end record;

begin
   --  Insert code here.
   null;
end Main;

报错信息:

9:38 -> error: Id is not visible
error: non-visible declaration at line 5
error: inherited discriminant not allowed here (RM 3.8 (12), 3.8.1 (6))

RM条款对应说明

你提到的RM条款内容正确:
RM 3.8(12/3)

表示非继承判别式的名称允许出现在类型声明内部,但不能出现在判别式部分。如果该判别式用于定义组件的约束、入口族的范围,或者派生类型定义中父子类型的约束,那么它的名称必须作为直接名称单独出现(不能作为更大表达式的一部分或扩展名称)。判别式不得用于定义标量组件的约束。

RM 3.8.1(6)

判别式直接名称必须解析为包含变体部分的完整类型声明中,已知判别式部分指定的判别式(称为变体部分的判别式)。变体中每个离散选择的预期类型是变体部分判别式的类型。

报错核心逻辑:声明Child_t时,直接继承Root_t但未显式声明自身判别式,此时父类型的Id属于继承判别式,Ada语法禁止在组件约束中直接引用继承判别式。必须显式声明自身判别式并传递给父类型,才能合法在组件定义中引用。

修改后代码的合规性

你修改后的写法完全合规:

type Child_t (Id : Natural) is limited new Root_t (Id => Id) with
   record
     component : Component_t(Id => Id);
   end record;

这里显式声明了Child_t的Id判别式,同时将其传递给父类型Root_t,此时组件定义中引用的Id是Child_t自身的非继承判别式,完全符合RM 3.8(12/3)的要求——自身判别式可用于定义组件约束,且以直接名称形式使用。

更简洁的解决方案

目前这个写法已是Ada语法要求下最简洁的合规方案。Ada类型系统明确要求:若要在派生类型的组件定义中使用判别式约束,必须显式声明派生类型自身的判别式(哪怕和父类型判别式完全一致),再传递给父类型,没有可绕过该要求的简化写法。

内容的提问来源于stack exchange,提问作者Albatros23

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:07:24