Разрешено ли использование конструктора с классами case? - PullRequest
2 голосов
/ 22 сентября 2010

У меня есть класс дел (назовем его Stuff), который я хочу иметь возможность создавать анонимные подклассы во время выполнения путем расширения признака (назовите его Marker). Вот фрагмент сеанса REPL, который иллюстрирует, что я пытаюсь сделать:

scala> trait Marker
defined trait Marker

scala> case class Stuff(i: Int)
defined class Stuff

scala> val a = Stuff(1)
a: Stuff = Stuff(1)

scala> val b = new Stuff(1) with Marker
b: Stuff with Marker = Stuff(1)

Обратите внимание, как a создается с использованием Stuff.apply(), тогда как в случае b я вызываю конструктор класса case.

У меня такой вопрос: создает экземпляры классов case с использованием кошерного конструктора? Мне кажется, что это так, поскольку обычные удобства, предоставляемые классами case, такие как ==, .equals(), и .hashCode(), все работает. Я скучаю по чему-нибудь, что могло бы обозначить то, что я делаю, Bad Thing (TM) ?

scala> a == b
res0: Boolean = true

scala> a.equals(b)
res1: Boolean = true

scala> a.hashCode == b.hashCode
res2: Boolean = true

Ответы [ 2 ]

3 голосов
/ 23 сентября 2010

Вот как реализовано Stuff.apply:

object Stuff {
  def apply(i: Int): Stuff = new Stuff(i)
}

Так что использование new Stuff.

совершенно не вредно.
3 голосов
/ 23 сентября 2010

На вопрос

- это создание экземпляров классов с использованием конструктора kosher

, ответ определенно да.Что-то вроде

val b = new Stuff(1)

не создает никаких проблем.Теперь new Stuff(1) with Marker отличается тем, что создан анонимный подкласс Stuff.Я верю, однако, что это все еще без проблем.Проблемы, о которых я знаю, возникают, когда классы прецедентов наследуются от других классов прецедентов, а вы этого не делаете.Но я могу ничего не знать.

РЕДАКТИРОВАТЬ: только что проверил соответствие в REPL:

scala> val b = new Stuff(1)
b: Stuff = Stuff(1)

scala> b match {case Stuff(x) => x}
res0: Int = 1

scala> b match {case Stuff(_) => true}
res1: Boolean = true
...