相当于 Ada 中的访问器

Equivalent to accessors in Ada

有没有办法在 Ada 中创建与 C# get/set 等效的方法?

我有这样的类型(在 Ada 中):

-- Ada :
type MyType is record 
    Value : Integer;
end record;

我想这样拆分值

-- Ada :
type MyType is record 
    ten  : Integer;
    unit : Integer;
end record;

但我想保留 MyType.Value(在许多只读文件中引用)。我想创建一个访问器,但我没有找到在 Ada 中如何做。我知道如何在 C# 中做 :

// C# :
int Value
{
    get
    {
        return this.ten * 10 + this.unit;
    }
    set
    {
        this.unit = value % 10;
        this.ten = value / 10;
    }
}

我想做什么:

-- ada :
MyType var := MyType'(Value => 15); -- unmodified code
var.Value := 65; -- can be modified like before

Integer ten := var.ten; -- new getter

正如我在 对你之前的问题的评论中所说,没有语言结构可以为你做这件事。根据您的用例,您可以使用受控类型:

type MyTypeView (Data : not null access MyType) is limited
  new Ada.Finalization.Limited_Controlled with record
   Value: Integer;
end record;

overriding procedure Initialize (Object : in out MyTypeView) is
begin
   Object.Value := Object.Data.ten * 10 + Object.Data.unit;
end Initialize;

overriding procedure Finalize (Object : in out MyTypeView) is
begin
   Object.Data.ten := Object.Value / 10;
   Object.Data.unit := Object.Value mod 10;
end Finalize;

这将允许您使用视图以您想要的方式更改值:

declare
   --  assuming MyObj is an object of type MyType
   View : MyTypeView (MyObj'Access);
   --  Initialize will be called, setting View.Value
begin
   --  can access value as "property"
   Do_Something (View.Value);
   --  can assign value as "property"
   View.Value := 123;
   --  when View goes out of scope, Finalize will be called, updating MyObj
end;

但是请注意,只要 View 存在,View.Value 就会与原始对象分离,这意味着在 end; 处,在创建 View 之后发生的 MyObj 的其他修改将被丢弃.在单线程程序中,这意味着您不能在当前视图存在时调用任何可能实例化同一对象的视图的子例程(并且不能在块内直接实例化该对象的第二个视图)。

这是私人类型的工作。

package Hidden is
   type T is tagged private;

   function New_T (Value : Integer) return T;

   function Value (Tee : T) return Integer;
   function Ten   (Tee : T) return Integer;
   function Unit  (Tee : T) return Integer;
private -- Hidden
   type T is tagged record
      Ten  : Integer;
      Unit : Integer;
   end record;
   ...
end Hidden;

现在你可以这样写了

V : T := New_T (42);
...
Put_Line (Item => V.Value'Image & V.Ten'Image & V.Unit'Image);
V := New_T (23);