记录判别式可以间接确定Ada中的数组长度吗?

时间:2018-08-28 03:10:43

标签: types record ada

我正在尝试说明一种特殊情况,其中几个数组的长度应该比正常的短,但是在判别式和数组的长度之间没有直接的关系。在通常情况下,简化的记录可能看起来像这样:

type Int_Array is array(Integer range <>);

type My_Record is
record
    A : Integer;
    B : Integer;
    C : Int_Array(1..10);
    D : Int_Array(1..6);
end record;

但是,如果某些判别式为320,则应如下所示:

type My_Record is
record
    A : Integer;
    B : Integer;
    C : Int_Array(1..4);
    D : Int_Array(1..2);
end record;

我一直在尝试一些它,但是什么都不能编译。这是我尝试过的一些事情:

type My_Record(Disc : Positive) is
record
    A : Integer;
    B : Integer;
    C : Int_Array(1..(if Disc = 320 then 4 else 10));
    D : Int_Array(1..(if Disc = 320 then 2 else 4));
end record;

但这会导致错误“约束中的区别必须单独出现”。

如果我尝试:

type My_Record(Disc : Positive) is
record
    A : Integer;
    B : Integer;
    case Disc is
        when 320 =>
            C : Int_Array(1..4);
            D : Int_Array(1..2);
        when others =>
            C : Int_Array(1..10);
            D : Int_Array(1..4);
    end case;
end record;

C和D的定义相互冲突。我还可以使用其他技巧吗?

2 个答案:

答案 0 :(得分:4)

如果要使用.C.D来访问变量,而不管变量如何,可以使用访问器函数:

   type My_Record (IDisc : Positive) is record
      IA, IB : Integer;
      case Disc is
         when 320 =>
            C1 : aliased Int_Array (1 .. 4);
            D1 : aliased Int_Array (1 .. 2);
         when others =>
            C2 : aliased Int_Array (1 .. 10);
            D2 : aliased Int_Array (1 .. 4);
      end case;
   end record;

   type Int_Array_Accessor (Data : not null access all Int_Array) is
     limited null record with Implicit_Dereference => Data;
   function C (Object : in out My_Record) return Int_Array_Accessor is
     (Int_Array_Accessor'(if Object.Disc = 320 then
                          Object.C1'Access else Object.C2'Access));
   function D (Object : in out My_Record) return Int_Array_Accessor is
     (Int_Array_Accessor'(if Object.Disc = 320 then
                          Object.D1'Access else Object.D2'Access));

通过使用带有Implicit_Dereference的访问器,您可以将值分配为好像是记录字段一样。

答案 1 :(得分:2)

在case语句中,每种情况下使用不同的变量名。您的原始示例包含一些语法错误。

package foo is
   type Int_Array is array(Integer range <>) of Integer;
   type My_Record(Disc : Positive) is
      record
         A : Integer;
         B : Integer;
         case Disc is
         when 320 =>
            C : Int_Array(1..4);
            D : Int_Array(1..2);
         when others =>
            E : Int_Array(1..10);
            F : Int_Array(1..4);
         end case;
      end record;
end foo;