“trait”和“template trait”的区别是什么?

23

看着 Traversable 和 TraversableLike 的 scaladoc,我很难弄清它们之间的区别(除了一个扩展了另一个)。文档中唯一明显的区别是它说 Traversable 是“trait”,而 TraversableLike 是“template trait”。但是搜索“template trait”并没有揭示这个术语的定义。帮帮忙!

3个回答

24

XXXLike特性在添加Repr泛型参数方面起着重要作用。像filter、map和flatMap等应该返回相同集合类型的方法是在低级特性(TraversableLike)中实现的。为了编码它们的返回类型,这些特性接受它:

trait TraversableLike[+A, +Repr] ...
  ...
  def filter(p: A => Boolean): Repr = {
(对于map和flatMap而言,问题更加复杂,我不会在这里详细说明)
现在假设你有一种新的集合类型。你可以这样做:
 trait MyCollection[+A] extends TraversableLike[A, MyCollection]

但是如果有人想要扩展你的集合,他们将被困在从各种继承方法返回MyCollection的返回值中。

所以相反地,你创建了:

 trait MyCollectionLike[+A, +Repr] extends TraversableLike[A, Repr]

 trait MyCollection[+A] extends MyCollectionLike[A, MyCollection]

任何想要扩展你的集合的人都扩展MyCollectionLike


IttayD,这应该是Scala网站上的常见问题解答之一。至少有三种不同的方法可以实现“此方法的返回类型与继承类相同”的技巧 - 知道Scala集合库使用了哪种方法(因此很可能是首选机制)是更多Scala初学者应该展示的内容。 - Adam

24
我在 Scala 的常规用法中没有看到这个术语,我认为它是特定于 Scala 集合 API 设计的。您可以通过阅读The Architecture of Scala Collections(特别是“分解公共操作”一节)[1]和the Scala collections SID来了解更多信息。SID 的第 4.2 节是相关的,尽管它们在那里被称为“实现特征”:

诸如 Traversable 或 Vector 等集合类从实现特征继承所有具体方法实现。这些特征以 Like 后缀命名;例如,VectorLike 是 Vector 的实现特征,而 TraversableLike 是 Traversable 的实现特征。

简而言之,它们的目的既是为了将实现分离出来以便在集合层次结构外使用(例如StringOps扩展了TraversableLike但没有扩展Traversable),也是为了以这样一种方式因式分解公共操作,使得集合类型得到保留(详见IttayD's answer中的更全面的解释)。
我应该指出,除非你正在扩展集合层次结构,否则你真的不需要关心这些类。对于普通的使用,重点放在TraversableIterableSeq等特质上。如果你是Scala Collections API的新手,我建议从Scala 2.8 Collection API document开始,然后根据需要参考scaladoc。你不能期望通过浏览scaladoc来获得“大局观”。
[1] 感谢michid提供此链接。

2
非常感谢您的出色回答!然而,最后一句话让我有点沮丧:“你不能指望通过查看scaladoc来获得‘大局’”- 真是太遗憾了...我确实觉得在Java标准库的情况下(至少对于从1.1开始存在的“核心”包如java.lang、java.util等),通过查看javadoc我能够获得整体的情况。 - Adam

0

[...]Like类是实际集合类的实现类。在某种意义上,它们就像模板实现,实际集合类从中继承了大部分(如果不是全部)行为。

要获取非常详细且易于理解的概述,请阅读Scala集合的架构


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接