记录判别式能否在 Ada 中间接确定数组长度?
Can a record discriminant determine array lengths indirectly in 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;
但这会导致错误 "discriminant in constraint must appear alone"。
如果我尝试:
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的定义相互冲突。我可以使用其他技术吗?
在 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;
如果您想使用 .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
一起使用,您可以像分配记录字段一样分配值。
我试图解释一种特殊情况,在这种情况下,几个数组长度应该比正常长度短,但判别式和数组长度之间没有直接关系。在正常情况下,简化的记录可能如下所示:
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;
但这会导致错误 "discriminant in constraint must appear alone"。
如果我尝试:
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的定义相互冲突。我可以使用其他技术吗?
在 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;
如果您想使用 .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
一起使用,您可以像分配记录字段一样分配值。