Как назначить запись во вложенном агрегате в Ada - PullRequest
0 голосов
/ 17 октября 2018

Я пытаюсь инициализировать переменную записи, которая сама содержит вложенную запись, используя агрегат, но не может получить правильный синтаксис.Любая помощь приветствуется.

with Step; use Step;

package Pattern is   

   -- ADT
   type Pattern_Type is tagged private;

   -- ADT components
  type Bars_Type is private; 

  -- ADT instance methods
  function Tempo (This: Pattern_Type) return Integer;       
  function Bars (This: Pattern_Type)  return Bars_Type;    
  function Get_Next_Step(This: Pattern_Type ) return Step_Type;   

  -- Static methods
  function Get_Basic_Beat return Pattern_Type;

private

  type Bars_Type is range 0..2;                  
  Number_Of_Steps : constant Natural := 32;

  type Active_Step_Type is mod Number_Of_Steps;   
  type Steps_Type is array( Active_Step_Type ) of Step_Type;


  type Pattern_Type is tagged record
    Tempo             : Integer range 40..400;
    Bars              : Bars_Type := 1;
    Steps             : Steps_Type;
    Active_Step       : Active_Step_Type := 1;
  end record;                   

  -- Package variable
 Basic_Beat : Pattern_Type := 
   ( Tempo => 125, 
     Steps => Steps_Type'(1..31 => Step_Type'(Instrument => 'K', Velocity => 127, Offset => 0, Active => True)), 
     others => <> );

end Pattern;

... и в пределах steps.ads

package Step is

  -- ADT
  type Step_Type is tagged private;      

  -- ADT instance methods
  function Instrument (This : Step_Type) return Character;
  function Velocity (This : Step_Type) return Integer;
  function Offset (This : Step_Type) return Integer;
  function Active (This : Step_type) return Boolean;

private   

  type Step_Type is tagged record            
    Instrument  : Character := ' ';      
    Velocity    : Integer := 0; 
    Offset      : Integer := 0;      
    Active      : Boolean := false;
  end record;

end Step;

Я получаю эту ошибку сборки в GPS expected private type "Step_Type" defined at step.ads:4, found a composite type

Я пробовал различные комбинацииStep_Type '... line

1 Ответ

0 голосов
/ 17 октября 2018

У вас есть различные варианты в зависимости от ваших потребностей:

  1. Сделайте запись реализации Step_Type общедоступной, чтобы ее могли использовать другие несвязанные пакеты.Это явно нарушает инкапсуляцию.
  2. Добавьте функцию, которая может создавать Step_Type на основе входных параметров в общедоступной области пакета Step.Это мой личный предпочтительный метод.
  3. Сделать Pattern дочерним пакетом Step (обеспечивает отображение в приватном разделе).Я обычно делаю это только в том случае, если это имеет смысл иерархически.
  4. Поместите оба Step_Type и Pattern_Type в один пакет.Тогда их частные разделы также видны друг другу.Я также делаю это, только если это имеет смысл с тем, как я выложу дизайн.

Пример для # 2:

with Ada.Text_IO; use Ada.Text_IO;
procedure Hello is

    package Step is

      -- ADT
      type Step_Type is tagged private;      

      function Make
        (Instrument : Character;
         Velocity   : Integer;
         Offset     : Integer;
         Active     : Boolean)
         return Step_Type;

    private   

      type Step_Type is tagged record            
        Instrument  : Character := ' ';      
        Velocity    : Integer := 0; 
        Offset      : Integer := 0;      
        Active      : Boolean := false;
      end record;

      function Make
        (Instrument : Character;
         Velocity   : Integer;
         Offset     : Integer;
         Active     : Boolean)
         return Step_Type
      is (Instrument => Instrument, 
          Velocity   => Velocity, 
          Offset     => Offset, 
          Active     => Active);

    end Step;

    use Step;
    package Pattern is   

       -- ADT
       type Pattern_Type is tagged private;

       -- ADT components
      type Bars_Type is private; 



    private

      type Bars_Type is range 0..2;                  
      Number_Of_Steps : constant Natural := 32;

      type Active_Step_Type is mod Number_Of_Steps;   
      type Steps_Type is array( Active_Step_Type ) of Step_Type;


      type Pattern_Type is tagged record
        Tempo             : Integer range 40..400;
        Bars              : Bars_Type := 1;
        Steps             : Steps_Type;
        Active_Step       : Active_Step_Type := 1;
      end record;                   

      -- Package variable
     Basic_Beat : Pattern_Type := 
       ( Tempo => 125, 
         Steps => (others => Make('K',127,0,True)), 
         others => <> );

    end Pattern;


begin
  Put_Line("Hello, world!");
end Hello;
...