宝书课程#1:Ada 2005中的受限类型 --受限集合

宝书课程#1:Ada 2005中的受限类型

--受限集合

by Bob Duff—AdaCore

Translator:Dongfeng.Gu

让我们开始吧

一个Ada我所喜欢的特征是对于集合的“全覆盖规则”。例如,假设我们有一个记录类型:

   type Person is

      record

         Name : Unbounded_String;

         Age : Years;

      end record;

我们可以使用一个集合来创建一个这个类型的对象:

   X : constant Person :=

      (Name => To_Unbounded_String (”John Doe”),

       Age => 25);

全覆盖规则意思是所有的Person的成员必须在集合中记录。如果我们接着通过增加一个成员来修改Person类型:

   type Person is

      record

         Name : Unbounded_String;

         Age : Natural;

         Shoe_Size : Positive;

      end record;

我们忘记修改X,于是编译器将提醒我们。Case语句也同样有全覆盖规则,它提供一个近似的目的。

当然,我们可以通过使用“others”来击败全覆盖规则(通常用于数组集合与情形语句,也偶尔对记录集合有用):

   X : constant Person :=

      (Name => To_Unbounded_String (”John Doe”),

       others => 25);

根据Ada参考手册,“others”这里精确的表示“Age|Shoe_Size”。但那是错误的:“others”真实的含义是“其它所有成员,包含我们可能在下周或下年将添加的成员”。这意味着你不应该使用“others”,除非你非常确信它将适用于所有未创作的情形。

到目前为止,这都是旧新闻了--自从Ada83以来全覆盖规则一直被维护。这和Ada2005有什么关系呢?

假设我们有一个受限类型:

   type Limited_Person is limited

      record

         Self : Limited_Person_Access := Limited_Person'Unchecked_Access;

         Name : Unbounded_String;

         Age : Natural;

         Shoe_Size : Positive;

      end record;

这个类型有一个自引用,它对复制对象没有意义,因为Self将最后指向错误的地方。因此,我们希望使类型受限,来防止程序员意外地创建副本。总之,该类型可能是私有的,因此客户端程序员可能不会意识到这个问题。我们也可以通过受控类型来解决那个问题,但是受控类型是费开销的,并且会增加不必要的复杂度,如果没有必要的话,就不要使用受控类型。

Ada95中,对于受限类型的集合(声明)是非法的。因此,我们将面临一个艰难的选择:创建受限类型对象,并且像这样初始化它:

   X : Limited_Person;

   X.Name := To_Unbounded_String ("John Doe");

   X.Age := 25;

这里有一个全覆盖规则应该防止的维护问题。或许,使类型非受限,这样可以获得集合(声明)的福利,但却失去防止拷贝的能力。

Ada2005中,一个集合(声明)可以用于受限对象。我们可以说:

   X : aliased Limited_Person :=

      (Self => null, – Wrong!

       Name => To_Unbounded_String (”John Doe”),

       Age => 25,

       Shoe_Size => 10);

   X.Self := X'Access;

我们将在未来的宝书课程中看到“Self=>null”做了什么。

一个非常重要的要求需要指出:创建X的值必须现场实现,不可以在一个临时变量中创建一个集合声明,然后复制它到X,因为这将违反受限对象的整个出发点--你不可以复制它们。

 

猜你喜欢

转载自blog.csdn.net/adacore/article/details/85041419