8

我有几个函数,其唯一的参数要求是它具有某种可增长的集合(即它可以是队列、列表、优先队列等),因此我尝试创建以下类型别名:

type Frontier = Growable[Node] with TraversableLike[Node, Frontier]

与函数定义一起使用,如下所示:

def apply(frontier: Frontier) = ???

但类型别名返回错误“涉及类型 Frontier 的非法循环引用”。有没有办法绕过非法循环引用来使用类型别名或类似的东西?

一种解决方案是使用以下内容:

def apply[F <: Growable[Node] with TraversableLike[Node, F]](f: F) = ???

但是当函数定义看起来与类型别名完全相同时,这似乎增加了不必要的冗长。该类型也用于其他地方,因此类型别名将大大增加可读性。

4

1 回答 1

7

规范的第 4.3 节:

定义(第 4 节)和类型参数(第 4.6 节)的范围规则使得类型名称可以出现在其自身的边界或右侧。但是,如果类型别名递归地引用已定义的类型构造函数本身,则会出现静态错误。

所以不,没有办法直接做到这一点,但你可以用类型别名上的类型参数完成很多相同的事情:

type Frontier[F <: Frontier[F]] = Growable[Int] with TraversableLike[Int, F]

现在你只需要apply这样写:

def apply[F < Frontier[F]](frontier: F) = ???

仍然比您假设的第一个版本稍微冗长,但比写出整个内容要短。

您也可以只对存在类型使用通配符简写:

type Frontier = Growable[Node] with TraversableLike[Node, _]

现在你的第一个apply 将按原样工作。您只是说必须有某种适合该插槽的类型,但您不在乎它是什么。

但是,特别是在这种情况下,您是否有理由不使用它Traversable[Node]?它实际上会完成同样的事情,并且没有对其表示类型进行参数化。

于 2012-11-20T22:58:05.450 回答