2012-03-10 11 views
0

私はこのようなレコードタイプがある場合:Adaでは、どのようにレコードのサブタイプを作ることができますか?

type ABC is record 
     A : Integer; 
     B : Integer; 
    end record; 

がどのように範囲指定されている2つの整数型とABCのサブタイプを作成できますか? (NWSは、あなたがそれを行うことができない、言うように)それ自体は、あなたの質問に回答していないが代わりにAとBは整数であることの、彼らが配列されるならば、あなたは次の操作を行うことができます

+1

あなたはいません。サブタイプは列挙型、浮動小数点型、整数型などに適用されますが、レコードは適用されません。あなたの問題に関する詳細情報を提供すれば、より多くのことを助けることができるかもしれません。 – NWS

+0

'サブタイプXYZ​​はABCです;'は合法ですが、OPが求めているものではありません。 –

答えて

3

package Record_Subtypes is 

    type Int_Data is array (Integer range <>) of Integer; 

    type ABC (X_Min, X_Max, Y_Min, Y_Max : Integer) is record 
     A : Int_Data (X_Min .. X_Max); 
     B : Int_Data (Y_Min .. Y_Max); 
    end record; 

    subtype ABC_4_4 is ABC(X_Min => 1, X_Max => 4, 
          Y_Min => 1, Y_Max => 4); 

    subtype ABC_1_7_3_12 is ABC (X_Min => 1, X_Max => 7, 
           Y_Min => 3, Y_Max => 12); 
end Record_Subtypes; 

AレコードフィールドとBレコードフィールドは、レコード判別式のインデックスサブタイプを使用します。

これは私が時々使用したすてきなトリックです。読み込むバイト数が固定サイズのヘッダーで提供されるインターフェイス(ソケットなど)から可変長文字列を読み込むときに便利です。または列挙型判別式を持つバリアントレコードの場合は、そのレコードを特定のバリアントにサブタイプすることができます。

2

あなたはこのように、一般的すぎるを使用することができます:あなたはAとBのために異なる範囲をしたい場合は、次の2つの一般的なパラメータを使用する必要があると思います

generic 
    type Number is range <>; 
package Int_Record is 
    type ABC is record 
     A, B : Number; 
    end record; 
end Int_Record; 

使い方は次のようになります:

procedure Foo is 
    subtype My_Int is Integer range 1 .. 3; 
    package My_Int_Record is new Int_Record (Number => My_Int); 
    X : My_Int_Record.ABC; 
begin 
    X.A := 2; -- okay 
    X.B := 4; -- error! 
end Foo; 
0

考える:

type ABC is record 
    A : Integer; 
    B : Integer; 
end record; 

あなたが使用することができます

type XYZ is record 
    A : Positive; -- A is subtype of ABC.A 
    B : Natural; -- B is subtype of ABC.B 
end record; 

    function convert(Input: ABC) return XYZ is 
    begin 
    return Result : XYZ:= (A => Input.A, B => Input.B); 
    -- Put your exception handling here. 
    end convert; 
1

Ada 2012でいると我々はサブタイプの制限を課すことができ、我々は今Dynamic_Predicateを持っています次のようになります。

type ABC is record 
    A : Integer; 
    B : Integer; 
    end record; 

subtype XYZ is ABC 
    with dynamic_predicate => 
    ((XYZ.A in Positive) and 
    (XYZ.B not in Positive)) or else raise Constraint_Error; 
+0

(a)あなたは 'またはConstraint_Errorを上げることを意味すると思います! (b)RMでアスペクト定義として許可されているのはどこですか?私は、GNAT GPL 2013はそれを許可していますが(FSF GCC 4.8.0ではなく)、私はそれがここで理にかなっていることがわかります。 –

+0

GNAT GPL 2013では、 'or raise Constraint_Error'構文を使用すると、例外が宣言された行で報告されますが、トレースバックは失敗した使用を示します。もしそれを省略すると、失敗した使用時に 'Assert_Error'が報告されます。これははるかに役立ちます。 –

+0

はい、そうです、あなたはそれが 'または他のものを引き上げる'ことを前提としています。私はLRMの構造を見てみましたが、見つけられませんでした。 (私は、*私はcomp.lang.adaのRandyからそれについて学んだと思う)。 – Shark8

関連する問題