在 ada 编程语言中,有没有办法创建一个子类型,它采用不同位置的类型枚举?
In ada programming language, Is there a way to create a subtype which takes differently positioned enums of a type?
我正在尝试创建一个子类型,它采用某种类型的某些枚举,例如,
type Integers_Type is (1,2,3,4,5,6,7,8,9,10);
我想要这样的东西,
subtype Odd_Numbers_Type is Integers_Type (1,3,5,7,9);
我明白了,当我们使用一个类型的关键字subtype
时,我们需要使用范围,但问题是枚举不在一个系列中。
对于这种值过滤,我会使用 subtype predicates。
在你的情况下,根据 Keith 所说的修改你的枚举:
type Integers_Type is (ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN);
subtype Odd_Numbers_Type is Integers_Type
with Static_Predicate => Odd_Numbers_Type in ONE | THREE | FIVE | SEVEN | NINE;
如果你想使用数值类型而不是枚举,使用下面的
type Integers_Type is range 1 .. 10;
subtype Odd_Numbers_Type is Integers_Type
with Dynamic_Predicate => Odd_Numbers_Type mod 2 /= 0;
更多信息,您可以阅读the rationale
编辑:
对于枚举类型,以下使用 gnatmake -gnata -gnatVa test_enum.adb 进行编译,但会警告第 14 行的影响并在执行时失败,因为断言链接到静态谓词。
with Ada.Text_IO; use Ada.Text_IO;
Procedure Test_Enum is
type Integers_Type is (ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN);
subtype Odd_Numbers_Type is Integers_Type
with Static_Predicate => Odd_Numbers_Type in ONE | THREE | FIVE | SEVEN | NINE;
Test_I : Integers_Type := TWO;
Test_O : Odd_Numbers_Type := ONE;
begin
Put_Line("Test_I=" & Integers_Type'Image (Test_I));
Put_Line ("Test_O=" & Odd_Numbers_Type'Image (Test_O));
Test_O := Test_I;
Put_Line ("Test_O=" & Odd_Numbers_Type'Image (Test_O));
end Test_Enum;
对于整数类型,使用 gnatmake -gnata -gnatVa test_int.adb 编译命令,编译器会警告检查将在运行时失败,因为断言被触发。
with Ada.Text_IO; use Ada.Text_IO;
Procedure Test_Int is
type Integers_Type is range 1 .. 10;
subtype Odd_Numbers_Type is Integers_Type
with Dynamic_Predicate => Odd_Numbers_Type mod 2 /= 0;
Test_I : Integers_Type := 2;
Test_O : Odd_Numbers_Type := 1;
begin
Put_Line("Test_I=" & Integers_Type'Image (Test_I));
Put_Line ("Test_O=" & Odd_Numbers_Type'Image (Test_O));
Test_O := Test_I;
Put_Line ("Test_O=" & Odd_Numbers_Type'Image (Test_O));
end Test_Int;
在这两种情况下,删除 -gnata 标志将使程序在不处理谓词的情况下运行,因为断言已停用。
你混淆了枚举和整数,如果你来自像 C 这样的东西,这是一个 大 的区别:在 Ada 中,枚举是 not 仅仅是整数的标签。
Frédéric Praca 给出的答案是绝对正确的,但是 (a) 您可以在 numeric-types 上使用 Static_Predicate
; (b) 有一种方法可以完成您在问题标题中提出的问题,这与您在 question-body.
中提出的问题略有不同
使用 subtype-predicates 的问题是你失去了使用某些
的能力
(a) — Static_Predicate
Type Digit_Range is 0..9;
Subtype Odd_Digit is Digit_Range
with Static_Predicate => 1|3|5|7|9;
(b) — 枚举的位置
在 Ada 中有几个属性,其中有 Pos
& Val
和 Pred
& Succ
。给定一个枚举 (Type Example is (A,B,C,D,E);
,你可以说 Example'Pos(D)
将 return 3
,你可以说 Example'Val(1)
将 return B
.
你 可以 然后将它们结合起来创建 multiple-types,虽然这个 是 heavy-handed 而不是通常你想做什么。
Type Base_Numeric_Range is range 0..9;
Type Odds is range 1..Base_Numeric_Range'Pos(Base_Numeric_Range'Last)) - Base_Numeric_Range'Pos(Base_Numeric_Range'First)) / 2;
-- This is from memory, and untested; so probably wrong in the details.
Function Convert(X : Base_Numeric_Range) return Odds is
( Odds'Val((Base_Numeric_Range'Pos(X) / 2) + 1) );
Function Convert(X : Odds) return Base_Numeric_Range is
( Base_Numeric_Range'Val(Odds'Pos(X) * 2 - 1) );
我正在尝试创建一个子类型,它采用某种类型的某些枚举,例如,
type Integers_Type is (1,2,3,4,5,6,7,8,9,10);
我想要这样的东西,
subtype Odd_Numbers_Type is Integers_Type (1,3,5,7,9);
我明白了,当我们使用一个类型的关键字subtype
时,我们需要使用范围,但问题是枚举不在一个系列中。
对于这种值过滤,我会使用 subtype predicates。
在你的情况下,根据 Keith 所说的修改你的枚举:
type Integers_Type is (ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN);
subtype Odd_Numbers_Type is Integers_Type
with Static_Predicate => Odd_Numbers_Type in ONE | THREE | FIVE | SEVEN | NINE;
如果你想使用数值类型而不是枚举,使用下面的
type Integers_Type is range 1 .. 10;
subtype Odd_Numbers_Type is Integers_Type
with Dynamic_Predicate => Odd_Numbers_Type mod 2 /= 0;
更多信息,您可以阅读the rationale
编辑:
对于枚举类型,以下使用 gnatmake -gnata -gnatVa test_enum.adb 进行编译,但会警告第 14 行的影响并在执行时失败,因为断言链接到静态谓词。
with Ada.Text_IO; use Ada.Text_IO;
Procedure Test_Enum is
type Integers_Type is (ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN);
subtype Odd_Numbers_Type is Integers_Type
with Static_Predicate => Odd_Numbers_Type in ONE | THREE | FIVE | SEVEN | NINE;
Test_I : Integers_Type := TWO;
Test_O : Odd_Numbers_Type := ONE;
begin
Put_Line("Test_I=" & Integers_Type'Image (Test_I));
Put_Line ("Test_O=" & Odd_Numbers_Type'Image (Test_O));
Test_O := Test_I;
Put_Line ("Test_O=" & Odd_Numbers_Type'Image (Test_O));
end Test_Enum;
对于整数类型,使用 gnatmake -gnata -gnatVa test_int.adb 编译命令,编译器会警告检查将在运行时失败,因为断言被触发。
with Ada.Text_IO; use Ada.Text_IO;
Procedure Test_Int is
type Integers_Type is range 1 .. 10;
subtype Odd_Numbers_Type is Integers_Type
with Dynamic_Predicate => Odd_Numbers_Type mod 2 /= 0;
Test_I : Integers_Type := 2;
Test_O : Odd_Numbers_Type := 1;
begin
Put_Line("Test_I=" & Integers_Type'Image (Test_I));
Put_Line ("Test_O=" & Odd_Numbers_Type'Image (Test_O));
Test_O := Test_I;
Put_Line ("Test_O=" & Odd_Numbers_Type'Image (Test_O));
end Test_Int;
在这两种情况下,删除 -gnata 标志将使程序在不处理谓词的情况下运行,因为断言已停用。
你混淆了枚举和整数,如果你来自像 C 这样的东西,这是一个 大 的区别:在 Ada 中,枚举是 not 仅仅是整数的标签。
Frédéric Praca 给出的答案是绝对正确的,但是 (a) 您可以在 numeric-types 上使用 Static_Predicate
; (b) 有一种方法可以完成您在问题标题中提出的问题,这与您在 question-body.
使用 subtype-predicates 的问题是你失去了使用某些
的能力(a) — Static_Predicate
Type Digit_Range is 0..9;
Subtype Odd_Digit is Digit_Range
with Static_Predicate => 1|3|5|7|9;
(b) — 枚举的位置
在 Ada 中有几个属性,其中有 Pos
& Val
和 Pred
& Succ
。给定一个枚举 (Type Example is (A,B,C,D,E);
,你可以说 Example'Pos(D)
将 return 3
,你可以说 Example'Val(1)
将 return B
.
你 可以 然后将它们结合起来创建 multiple-types,虽然这个 是 heavy-handed 而不是通常你想做什么。
Type Base_Numeric_Range is range 0..9;
Type Odds is range 1..Base_Numeric_Range'Pos(Base_Numeric_Range'Last)) - Base_Numeric_Range'Pos(Base_Numeric_Range'First)) / 2;
-- This is from memory, and untested; so probably wrong in the details.
Function Convert(X : Base_Numeric_Range) return Odds is
( Odds'Val((Base_Numeric_Range'Pos(X) / 2) + 1) );
Function Convert(X : Odds) return Base_Numeric_Range is
( Base_Numeric_Range'Val(Odds'Pos(X) * 2 - 1) );