如何解决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成员。
额外代码修正
原始代码存在两处语法错误,需修正:
- 私有部分的
T_MyType_Pirvate_Part拼写错误,改为T_MyType_Private_Part - 所有
end record语句后必须添加分号,符合Ada语法要求
内容的提问来源于stack exchange,提问作者A.Pissicat
相关产品推荐
相关产品推荐

