如何在 Ada 的嵌套聚合中分配记录
How to assign a record within a nested aggregate in Ada
我正在尝试初始化一个记录变量,该变量本身包含使用聚合的嵌套记录,但似乎无法获得正确的语法。任何帮助表示赞赏。
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'... 行的各种组合
根据您的需要,您有不同的选择:
- 将Step_Typepublic的实现记录下来,以便其他不相关的包可以使用。这显然破坏了封装。
- 在Step包的public区域添加一个可以根据输入参数创建Step_Type的函数。这是我个人比较喜欢的方法。
- 使 Pattern 成为 Step 的子包(提供对私有部分的可见性)。我通常只在层次结构有意义的情况下才这样做。
- 将 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;
我正在尝试初始化一个记录变量,该变量本身包含使用聚合的嵌套记录,但似乎无法获得正确的语法。任何帮助表示赞赏。
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'... 行的各种组合
根据您的需要,您有不同的选择:
- 将Step_Typepublic的实现记录下来,以便其他不相关的包可以使用。这显然破坏了封装。
- 在Step包的public区域添加一个可以根据输入参数创建Step_Type的函数。这是我个人比较喜欢的方法。
- 使 Pattern 成为 Step 的子包(提供对私有部分的可见性)。我通常只在层次结构有意义的情况下才这样做。
- 将 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;