Что еще более характерно для Scala: черта TraitA расширяет TraitB или черта TraitA {self: TraitB =>} - PullRequest
19 голосов
/ 31 августа 2011

Помимо аспекта наследования, есть ли разница между следующими шаблонами классов:

1| trait TraitA extends TraitB

2| trait TraitA { self: TraitB => }

Я хотел бы разделить обязанности между TraitA и TraitB, но первый не может функционировать без последнего.

Как бы вы выразили это намерение? Для меня решение [2] было бы более естественным подходом. Однако я не хочу налагать бремя на то, что разработчики смешивают то, что нужно смешивать.

1 Ответ

16 голосов
/ 31 августа 2011

Обычно я предпочитаю [1], потому что, как вы говорите, разработчик не обременен смешиванием (подтипом) TraitB. Возможно, [2] предпочтительнее, если по какой-то причине желательно , а не , чтобы наследовать конкретные реализации в TraitB и заставить разработчика сделать выбор среди подтипов TraitB. Тем не менее, [1] столь же гибок.

Я склонен использовать [2] только в случае необходимости, например, когда тип не является известным классом или признаком,

// Here, Matrix cannot extend type parameter Repr
trait Matrix[+Repr <: Matrix[Repr]] { self: Repr =>
  ...
}

Обновление. Вот еще одна небольшая разница,

trait B
trait A { self: B => }
def g(ab: A): B = ab // Type mismatch: found A, required B

Это немного раздражает необязательное ограничение , не позволяющее использовать A в качестве B, даже если этот тип включен.

...