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

明らかな方法 (宣言ブロック) をローカル プロシージャに変換することで、記載されている要件を技術的に満たすことができます。

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 に答える
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 );

とはいえ、これはおそらく最良の方法ではなく、declare-block を使用する方が保守が容易になる可能性が非常に高くなります。

于 2013-04-28T03:27:59.187 に答える
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>ため、ケースに書き込むことはできないことに注意してください(RM 3.5.4を参照)expr

于 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 に答える