scala - передает аннотированный класс self type дочернему объекту - PullRequest
5 голосов
/ 05 марта 2012

извините, если это глупое название, я не знаю, как это выразить ясно

скажем, у меня есть черта логирования:

trait Logging {
    def log(s:String)
}

, а затем некоторая реализация

trait PrintlnLog extends Logging {
    def log(s:String) { println(s) }
}

который я использую вот так

class SomeProcess { this:Logging =>
   def doSomeJunk() {
      log("starting junk")
      ...
      log("junk finished")
   }
}

я мог бы использовать этот класс как

val p = new SomeProcess () with PrintLog
p.doSomeJunk()

что теперь, если у меня есть это

class SubProcess { this:Logging => 
   def doSubJunk() {
      log("starting sub junk")
      ...
      log("finished sub junk")
   }
}

class ComplexProcess { this:Logging => 
   def doMoreJunk() {
       log("starting more junk")
       val s = new SubProcess with // ??? <-- help!
       s.doSubJunk()
       log("finished more junk")
   }
}

в ComplexProcess я хочу создать экземпляр смешивания SubProcess в той же особенности ведения журнала, которая была смешана с ComplexProcess, но ComplexProcess не знает, что это такое. есть ли способ получить ссылку на него?

Ответы [ 3 ]

4 голосов
/ 05 марта 2012

Вы не можете этого сделать.В этом случае вы, вероятно, сделаете что-то вроде этого:

trait WithSubProcess {
  def s: SubProcess
}

class ComplexProcess { this: Logging with WithSubProcess ... }
2 голосов
/ 07 марта 2012

Ответ по определению - нет.Scala является языком статической типизации, поэтому эта информация действительно доступна только во время компиляции.С более обширным API-интерфейсом для рефлексии и некоторыми хаки для компоновки / сборки это может быть возможно в будущем, хотя это опасно близко к аспектно-ориентированному программированию, как упоминал Паоло.

1 голос
/ 06 марта 2012

Ведение журнала является типичным случаем для аспектно-ориентированного программирования.Вы можете попробовать использовать AspectJ с scala: см. эту статью Джонаса Бонера

...