首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Ada中,如何递归映射和内存管理类型本身

在Ada中,如何递归映射和内存管理类型本身
EN

Stack Overflow用户
提问于 2017-07-23 03:21:44
回答 2查看 276关注 0票数 0

我已经在这个小问题上挣扎了一段时间。我正在尝试创建自己的内部JSON结构实现。挑战是,在Ada中,我必须使用访问类型来使其成为递归的,并且如果我没有严格控制它,访问类型就有泄漏的风险。为了对其进行控制,我将我为Node类型提供的Get (Source:...)Set (Target:...; Value:...)函数/过程保留为私有,这些函数/过程将尝试验证和处理任何现有的矢量(json数组)或映射(json对象)元素。为了进一步确保我使用Ada2012的稳定特性并在内容超出范围时捕获它们,我尝试使用Protected_Controlled类型和“管理”Ada库,但发现容器库不能处理受保护的类型,所以我使用简单的控制。Finalize (...)过程适用于任何矢量或贴图类型,并递归地释放Node_Value.Reference。

我的问题是,我是否正确地应用了Ada 2012,否则我如何创建一个内存管理的递归类型,可以是向量/映射或字符串/数字?

代码语言:javascript
复制
private

    ...

   type Node_Access is access Node;
   type Node_Value is new Ada.Finalization.Controlled with record
      Reference : Node_Access;
   end record;
   overriding procedure Initialize (Item : in out Node_Value);
   overriding procedure Adjust (Item : in out Node_Value);
   overriding procedure Finalize (Item : in out Node_Value);

    ...

   package Of_Array is new Ada.Containers.Indefinite_Vectors (Natural, Node_Value);
   package Of_Object is new Ada.Containers.Indefinite_Ordered_Maps (Wide_String, Node_Value);

   type Node is record
      ...
      Vector    : aliased Of_Array.Vector;
      Object    : aliased Of_Object.Map;
   end record
     with Size => 96;

   procedure Free is new Ada.Unchecked_Deallocation (Node, Node_Access);
EN

回答 2

Stack Overflow用户

发布于 2017-07-25 01:41:01

这样做的方法(在我看来)是使用OOP,并将抽象元素作为表示可以存储的不同类型的数据的类型族的根节点。

然后,可以将元素数组实现为以抽象元素类型为根的类的向量。一个“对象”可以被实现为一个哈希表,以字符串键和以抽象元素类型为根的类作为值。

票数 1
EN

Stack Overflow用户

发布于 2017-08-23 20:53:57

不带访问类型的自引用类型是类型扩展与不确定容器结合使用的有效方法。一个简单的例子是S-表达式,或性别。Sex可以是一个原子,也可以是一个包含零个或多个性别的列表。能够做到这一点的正确方法是

代码语言:javascript
复制
with Ada.Containers.Indefinite_Vectors;
package Sexes is
   type Sex is private;
   -- Operations on Sex
private -- Sexes
   package Sex_List is new Ada.Containers.Indefinite_Vectors
      (Index_Type => Positive, Element_Type => Sex); -- Illegal

   type Sex (Is_Atom : Boolean := False) is record
      case Is_Atom is
      when False =>
         Value : Atom;
      when True =>
         List : Sex_List.Vector;
      end case;
   end record;
end Sexes;

但是Ada不允许这样做。我们可以使用类型扩展来解决这个问题:

代码语言:javascript
复制
private -- Sexes
   type Root is tagged null record;

   package Sex_List is new Ada.Containers.Indefinite_Vectors
      (Index_Type => Positive, Element_Type => Root'Class);

   type Sex (Is_Atom : Boolean := False) is new Root with record
      case Is_Atom is
      when False =>
         Value : Atom;
      when True =>
         List : Sex_List.Vector;
      end case;
   end record;
end Sexes;

这是合法的。唯一的问题是,您必须将从List获取的任何内容转换为Sex (在您的情况下是Node )。

HTH;很抱歉回复晚了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45258325

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档