让我说我有
function x return boolean is
type range0 is range 1..1;
begin
canse x is
when 4=> range0:=firstArray'range;
when 5=> range0:=secondArray'range;
when 6=> range0:=1..100;
end case;
end x;
基本上我想在旅途中改变range0的范围?如何在不使用声明块的情况下完成此操作?
答案 0 :(得分:2)
基本上我想在旅途中改变range0的范围?如何在不使用声明块的情况下完成此操作?
唔... 在Ada 2012中,您可以使用if和case表达式,因此您可以使用以下内容:
Type Array_Type is Array(Positive Range <>) of Integer;
Array_1 : Array_Type(1..128);
Array_2 : Array_Type(33..63);
-- your variant-selector
Use_1 : constant Boolean:= True;
-- Your variant-range here:
Subtype Variant_Range is Positive Range
(if Use_1 then Array_1'First else Array_2'First)
..(if Use_1 then Array_1'Last else Array_2'Last);
Array_3 : Array_Type( Variant_Range );
所有这一切,这可能不是最好的方法,使用声明块很可能更容易维护。
答案 1 :(得分:2)
您可以通过将明显的方式(声明块)转换为本地过程来技术上满足所述要求:
function x return boolean is
procedure use_dynamic_range(first,last : in integer) is
type range0 is new integer range first .. last;
begin
null;
end use_dynamic_range;
begin
case z is
when 4=> use_dynamic_range(firstArray'first, firstArray'last);
when 5=> use_dynamic_range(secondArray'first, secondArray'last);
when 6=> use_dynamic_range(1,100);
end case;
end x;
因为它是一个本地过程,它在与等效声明块相同的范围内执行,因此它可以访问X中可见的所有内容,因此您不需要将它传递给一个巨大的参数列表。
答案 2 :(得分:1)
如下:
function x return Boolean is
type Range_Info_Type is
record
First : Integer;
Last : Integer;
end record;
function Get_Range_Info_Type return Range_Info_Type is
begin
case z is
when 4=> return Range_Info_Type'(First => firstArray'First,
Last => FirstArray'Last);
when 5=> return Range_Info_Type'(First => secondArray'First,
Last => secondArray'Last);
when 6=> return Range_Info_Type'(First => 1,
Last => 100);
when others => return Range_Info_Type'(First => 1,
Last => 1);
end case;
end;
MyTypeInfo : constant Range_Info_Type := Get_Range_Info_Type;
-- Now declare the actual type I want to use.
type range0 is new Integer range MyTypeInfo.First .. MyTypeInfo.Last;
begin
return true;
end x;
声明块可能更容易理解,应该这样做。
请注意,由于type range0 is range <expr>..<expr>
应为静态表达式,因此无法在您的案例中编写expr
答案 3 :(得分:0)
Ada 2012的另一个非声明块回答:
Minimum : Integer := Integer'First; --' SO highlight correction
Maximum : Integer := Integer'Last; --' *same*
Function In_Range(X : Integer) return Boolean is
( X in range Minimum..Maximum );
Subtype Variant_Range is Integer Range Integer
with Dynamic_Predicate => In_Range(Variant_Range);
警告:虽然 应该工作,但我还没有测试过。