Domanda

Se ho un tipo di record come questo:

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

Come posso creare un sottotipo di ABC con due tipi di integer il cui intervallo è specificato?

È stato utile?

Soluzione

Mentre non risponde alla tua domanda per sé (come dice NWS, non puoi farlo), se invece di A e B sono numeri interi, dovevano essere array, puoi fare quanto segue:

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

I campi di record A e B utilizzano quindi il sottotipo dell'indice come fornito dai discriminanti record.

Questo è un bel trucco che ho usato di volta in volta, utile quando si legge in stringhe a lunghezza variabile da un'interfaccia (come un socket) in cui il numero di byte da leggere è fornito tramite intestazione di dimensioni fisse;O nel caso di un record variante con un'enumerazione discriminante, posso sottotipo del record a una variante specifica.

Altri suggerimenti

È possibile utilizzare anche un generico, come questo:

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

Se si desidera diversi intervalli per A e B, dovresti usare due parametri generici.

L'utilizzo sarebbe come questo:

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

In Ada 2012 ora abbiamo Dynamic_Predicate con cui possiamo imporre restrizioni sottotinguente, come segue:

.

Dato:

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

È possibile utilizzare:

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top