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

如何解决Ada语言中私有类型T_MyType无法访问Toto成员的问题?

Ada私有类型成员访问错误解决方法

问题重现

你尝试定义带私有部分的标记类型,但外部包访问成员Toto时触发报错:

no selector "Toto" for type "T_MyType" defined at MyFile.ads

你的代码如下:

包规范(MyFile.ads)

package MyPackage is
  type T_MyType is tagged private;
private
  type T_MyType_Private_Part;
  type T_MyType_Private_Part_Access is access T_MyType_Pirvate_Part; -- 拼写错误:Pirvate → Private
  type T_MyType is tagged record
    Toto : Boolean;
  end record -- 缺少分号
end MyPackage;

包体(MyFile.adb)

package body MyPackage is
   type T_MyType_Private_Part is record
     Private_Toto : Boolean;
   end record -- 缺少分号
end MyPackage;

问题原因

当在包规范中声明type T_MyType is tagged private;时,该类型对外部包是完全不透明的私有类型——外部仅能识别这是一个标记类型,无法查看其内部记录结构或成员。即便你在私有部分定义了Toto,外部也没有直接访问的权限。

解决方案

根据需求,可选择以下两种常用方案:

方案1:公开需外部访问的成员

如果Toto是允许外部直接访问的公共成员,将其定义移到包的公共可见区域,仅隐藏真正需要保密的部分:

package MyPackage is
  type T_MyType is tagged record
    Toto : Boolean; -- 公共成员,外部可直接访问
  end record;
private
  type T_MyType_Private_Part is record
    Private_Toto : Boolean; -- 私有成员,仅包内可见
  end record;
  -- 若需关联私有部分,可嵌入访问类型(可选)
  type T_MyType_Private_Part_Access is access T_MyType_Private_Part;
end MyPackage;

方案2:提供公共访问器方法

如果不想直接暴露Toto的访问权限,可在包规范中定义Getter/Setter方法,通过方法控制成员访问:

包规范修改

package MyPackage is
  type T_MyType is tagged private;

  -- 获取Toto的值
  function Get_Toto (Obj : T_MyType) return Boolean;
  -- 设置Toto的值
  procedure Set_Toto (Obj : in out T_MyType; Value : Boolean);

private
  type T_MyType_Private_Part is record
    Private_Toto : Boolean;
  end record;
  type T_MyType is tagged record
    Toto : Boolean;
    Private_Part : T_MyType_Private_Part; -- 直接包含私有部分,无需动态访问类型(按需选择)
  end record;
end MyPackage;

包体实现访问器

package body MyPackage is
  function Get_Toto (Obj : T_MyType) return Boolean is
  begin
    return Obj.Toto;
  end Get_Toto;

  procedure Set_Toto (Obj : in out T_MyType; Value : Boolean) is
  begin
    Obj.Toto := Value;
  end Set_Toto;
end MyPackage;

外部包可通过Get_Toto(MyVar)和Set_Toto(MyVar, True)操作Toto成员。

额外代码修正

原始代码存在两处语法错误,需修正:

  1. 私有部分的T_MyType_Pirvate_Part拼写错误,改为T_MyType_Private_Part
  2. 所有end record语句后必须添加分号,符合Ada语法要求

内容的提问来源于stack exchange,提问作者A.Pissicat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 12:32:04