Подтвердить что ты не робот

В чем разница между "признаком" и "шаблонной чертой"?

Глядя на scaladoc для Traversable и TraversableLike, мне сложно определить, какая разница между ними (за исключением того, что одна расширяет другую). Единственная очевидная разница в документации заключается в том, что он говорит, что Traversable является "признаком", а TraversableLike - "шаблонной чертой". Но googling для "шаблонной черты" не раскрывает определения для этого термина. Помогите!

4b9b3361

Ответ 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 Коллекции.