【问题标题】:Recursive visibility of symbols in Ada packagesAda 包中符号的递归可见性
【发布时间】:2014-05-17 21:09:26
【问题描述】:

假设我有一个通用向量库。为了方便使用,我想实例化各种常用形式的向量库,并在单个包中可见。

我正在尝试这个:

with GenericVector;

package Vectors is
    package Vectors3 is new GenericVector(3);
    use all type Vectors3.Vector;
    subtype Vector3 is Vectors3.Vector;

    package Vectors4 is new GenericVector(4);
    use all type Vectors4.Vector;
    subtype Vector4 is Vectors4.Vector;
end;

最终目标是我希望能够做到 with Vectors; use Vectors; 并最终得到 Vector3Vector4 直接可用的 Just Work 类型。

当然,上面的代码不起作用。看起来use all type 语句将附加到指定类型的定义导入到包规范中,但这些定义并没有导出给Vectors 的用户。我必须改用with Vectors; use Vectors; use all type Vectors.Vectors3;。这有点糟糕。

我该怎么做?

【问题讨论】:

  • 包中的use 子句只允许您在包内使用类型,并导出您声明的子类型。除了use Vectors,您将能够在包外声明Vector3 变量,但不会导出对子类型的所有操作,因此您将无法在包外使用V1 + V2。跨度>

标签: packages ada ada2012


【解决方案1】:

您可以简单地创建 Vector3Vector4 新类型,而不仅仅是子类型。这将在Vectors 中隐式声明来自GenericVector 的所有继承的原始操作。

【讨论】:

  • 但如果我这样做了,它们的类型就不会与Vectors3.VectorVector4.Vector 兼容,对吧?在那些定义为返回Vectors3.Vector的类型上调用方法时,这不会给我带来问题吗?
  • 是的。但是,当您拥有Vector3 时,为什么还要在Vectors3.Vector 上声明新操作?
  • 我不是;我担心GenericVector.Vector 上定义的方法返回 GenericVector.Vector 会停止工作。但事实证明情况并非如此,而且这种方法效果很好(尽管我在使用一些更复杂的泛型时确实遇到了一些麻烦)。谢谢。
【解决方案2】:

use Vectors 让您可以直接看到在Vectors 中声明的那些标识符,包括那些隐式声明的标识符。 (隐式声明是诸如"+""-"、声明新整数类型时的运算符和声明派生类型时的继承操作。)但它不会让您直接看到其他任何东西。特别是,use不是可传递的,因为use all type Vectors3.Vector 没有在Vectors 中声明任何新标识符。

您可以通过为您希望use Vectors 用户看到的所有内容声明重命名标识符来实现此目的。 (对于类型,您必须使用 subtype,因为 Ada 中没有类型重命名。)例如在Vectors:

function Dot_Product (V1, V2 : Vectors3.Vector) return Float
   renames Vectors3.Dot_Product;

(我只是在猜测GenericVectors 中的操作可能是什么样子。)现在,任何说use Vectors 的地方都可以直接使用Dot_Product。不过,您必须为每个标识符做这样的事情。如果它们很多,这可能不是一个可行的解决方案。 (重命名声明不必使用相同的名称Dot_Product。)

虽然您无法获得这种传递可见性可能看起来很烦人,但替代方案可能会变得更烦人,因为您无法查看 Vectors 并查看哪些标识符会被use Vectors;结果可能是意外的名称冲突或其他意外。

【讨论】:

    猜你喜欢
    • 2012-09-24
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 2014-01-31
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    相关资源
    最近更新 更多