0

可以说我有

    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 的范围?我如何在不使用声明块的情况下完成此操作?

4

4 回答 4

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 );

尽管如此,这可能不是最好的方法,使用声明块很可能会更容易维护。

于 2013-04-28T03:27:59.187 回答
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 中可见的所有内容,因此您不需要传递给它一个巨大的参数列表。

于 2013-04-28T08:53:14.527 回答
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应该是静态表达式(参见 RM 3.5.4)

于 2013-04-28T10:21:07.590 回答
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);

警告:虽然这应该可以,但我还没有测试过。

于 2013-04-28T03:34:30.010 回答