перегрузка конструктора класса case с неявным параметром?

Я пытаюсь определить класс case с некоторыми параметрами, которые имеют значение по умолчанию, но для значения по умолчанию требуется неявный параметр. Я пробовал что-то вроде этого:

case class ChannelLatches(started: TestLatch, stopped: TestLatch)(implicit system: ActorSystem) {
  def this()(implicit system: ActorSystem) = this(new TestLatch(), new TestLatch())(system)
}

и это:

case class ChannelLatches(started: TestLatch, stopped: TestLatch)(implicit system: ActorSystem) {
   def this()(implicit system: ActorSystem) = this(new TestLatch(), new TestLatch())(system)
}

но в обоих случаях компилятор не распознает мой новый конструктор. Любые указатели?


person jxstanford    schedule 04.03.2012    source источник
comment
case class ChannelLatches (начато: TestLatch = новый TestLatch, остановлено: TestLatch = новый TestLatch) (неявная система: ActorSystem) { }   -  person Eastsun    schedule 04.03.2012
comment
Это то, что я пробовал изначально, но компилятор выдает ошибку типа: не удалось найти неявное значение для системы параметров: akka.actor.ActorSystem. Я предполагаю, что система определена в последующем списке параметров.   -  person jxstanford    schedule 04.03.2012


Ответы (1)


Проблема не в классе case или его конструкторе. Когда вы получаете ошибку компиляции, например

scala> val channelLatches = new ChannelLatches
<console>:11: error: could not find implicit value for parameter system: ActorSystem
       val channelLatches = new ChannelLatches
                            ^

это означает, что у вас нет неявной переменной типа ActorSystem, доступной в качестве единственного идентификатора в области видимости.

Оба ваших примера кода (это точно такой же код, верно?) и пример @Eastsun являются совершенно законным кодом:

scala> class ActorSystem
defined class ActorSystem

scala> class TestLatch
defined class TestLatch

scala> case class ChannelLatches(started: TestLatch = new TestLatch, stopped: TestLatch = new TestLatch)(implicit system: ActorSystem)
defined class ChannelLatches

scala> implicit val actor = new ActorSystem
actor: ActorSystem = ActorSystem@586f403e

scala> val channelLatches = new ChannelLatches
channelLatches: ChannelLatches = ChannelLatches(TestLatch@521a74af,TestLatch@46e2b745)

Обратите внимание на неявный актер val, который позволяет компилятору неявно указывать отсутствующий параметр.

См. Знакомство со Scala: неявные параметры для ознакомления с неявными параметрами.

--- Редактировать 2012-03-05: Добавлен альтернативный пример, где ChannelLatches является внутренним классом Something.

Если вы хотите, чтобы ChannelLatches был внутренним классом чего-либо, вам действительно не нужно передавать экземпляр ActorSystem экземплярам внутреннего класса, поскольку внутренние классы могут получать доступ к значениям из внешних объектов. Обзор Scala: внутренние классы

scala> class ActorSystem
defined class ActorSystem

scala> class TestLatch
defined class TestLatch

scala> class Something(implicit val as: ActorSystem) {
     |   case class ChannelLatches(started: TestLatch, stopped: TestLatch) {
     |     def this() = this(new TestLatch(), new TestLatch())
     |  
     |     def actorSystem = as
     |   }
     | }
defined class Something

scala> implicit val as = new ActorSystem
as: ActorSystem = ActorSystem@5481be8a

scala> val s = new Something
s: Something = Something@7139acf

scala> val cl = new s.ChannelLatches
cl: s.ChannelLatches = ChannelLatches(TestLatch@38764254,TestLatch@5bfcb5c1)

scala> cl.actorSystem == as
res0: Boolean = true
person Lauri    schedule 04.03.2012
comment
Я пытаюсь найти способ, чтобы ChannelLatches не был внутренним классом чего-то с неявной системой в области видимости. Вот почему я определял неявный параметр класса case (хотя, конечно, в данном контексте это не работает). ActorSystem должен быть предоставлен вызывающей стороной. - person jxstanford; 05.03.2012