Когда использовать собственные ссылки или композицию? - PullRequest
3 голосов
/ 24 августа 2011

Посмотрите на следующий фрагмент кода:

trait T { def y = println("hello") }
class A {
   self: T =>
   def x = y
}
abstract class B {
   val self: T
   def x = self.y
}

val a = new A with T
val b = new B with T {
   val self = this
}
a.x
b.x

Класс A и B имеют ссылку на черту T, A имеет собственную ссылку и B использует композицию.

Здесь я вижу только два отличия: первое - создание новых объектов. и второй в доступе к T.

В B больше синтаксического сахара, мне не нужно явно получать доступ ссылаться на себя, и мне не нужно связывать переменную.

Есть ли другие различия и есть ли ситуации, в которых следует предпочитать вместо другого?

Ответы [ 2 ]

1 голос
/ 24 августа 2011

Ваш вопрос, по-видимому, исключает простое наследование.Для A тип self не имеет преимуществ по сравнению с class A extends T.Для B, если вы намереваетесь создать его только в том виде, в котором оно написано, то есть с self = this, extends также хорош (и намного проще)

Я не думаю, что их так много используютслучай для собственного типа (но это не обсуждение композиции против наследования)

Один из них заключается в том, чтобы заставить признак быть экземпляром только как подтип другого типа, еще не известного, потому что он выглядит как типпараметр или член абстрактного типа.Например, trait X[A] {self: A => ...} Вы можете взглянуть на этот реалистичный пример на сайте scala с типом member.

Другой случай, когда вы создаете модули, а не экземпляры, в частности, когда у модуля есть члены типа, что делает композицию выполнимой только во время компиляции.Это более или менее связано с CakePattern.

Композиция (с абстрактным значением val или параметром конструктора), безусловно, имеет сильное преимущество в том, что вы можете передавать внешний экземпляр T, делить его между различными экземплярами B, выбирать его гораздо более динамично.экземпляры могут передаваться и возвращаться из функций, миксины не могут

1 голос
/ 24 августа 2011

В scala я использую композицию только тогда, когда мне нужно «смешать» класс с другим.В вашем примере, если бы T был классом:

class T { def y = println("hello") }

, то new X with T было бы невозможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...