Глядя на scaladoc для Traversable и TraversableLike, мне сложно определить, какая разница между ними (за исключением того, что одна расширяет другую). Единственная очевидная разница в документации заключается в том, что он говорит, что Traversable является "признаком", а TraversableLike - "шаблонной чертой". Но googling для "шаблонной черты" не раскрывает определения для этого термина. Помогите!
В чем разница между "признаком" и "шаблонной чертой"?
Ответ 1
Я не видел эту терминологию в общем использовании в Scala, и я думаю, что она специфична для дизайна API коллекций Scala. Вы можете узнать больше, прочитав Архитектура Scala Коллекции (особенно раздел "Фактор разборки общих операций" ) [1] и сборник Scala SID. §4.2 SID имеет значение, хотя они упоминаются как "черты реализации":
Классы сбора данных, такие как Traversable или Vector, наследуют все их реализации конкретных методов из признака реализации. Эти черты называются с атрибутом Like suf fix; например VectorLike - это признак реализации для Vector и TraversableLike - это признак реализации для Traversable.
Короче говоря, их цель состоит в том, чтобы разделить реализацию для использования вне иерархии коллекций (например, StringOps
extends TraversableLike
, но не Traversable
)), а также разложить общие операции таким образом, чтобы сохранить тип коллекции (см. ответ IttayD для более подробного объяснения).
Я должен отметить, что вам действительно не нужно беспокоиться об этих классах, если вы не расширяете иерархию коллекций. Для обычного использования сосредоточьтесь на тэгах Traversable
, Iterable
, Seq
и т.д. Если вы новичок в API Scala Collections API, я бы предложил начать с Scala 2.8 Collection API document, а затем ссылаться на scaladoc по мере необходимости. Вы не можете ожидать получения "большой картины", просматривающей скаладок.
[1] кредит идет на michid для этой ссылки
Ответ 2
Признаки XXXLike играют важную роль при добавлении параметра Gener. Методы, которые должны возвращать один и тот же тип коллекций, например фильтр, 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
Ответ 3
[...] Подобные классы являются классами реализации для фактических классов коллекции. В некотором смысле они действуют как реализация шаблонов, из которых большинство - если не все - поведение наследуется фактическими классами коллекции.
Для очень подробного и доступного обзора читайте Архитектура Scala Коллекции.