0

阅读了有关delayedInit 的各种帖子后,我惊讶地发现它实际上每次都被构建期间的各个子类调用。我不确定我是否相信这一点,但后来我做了下面的测试。无论如何,我的问题是,delayedInit 听起来像是一种有用的机制,可以从抽象类驱动某种最终操作(例如,可能通知另一个对象创建完成)。如果它只被调用一次,这将是有道理的。但是,如果您冒着被重复调用的风险而没有在它的参数中传递任何其他有用的信息,那么如何从函数中构建任何类型的有用构造呢?我怎么能将它编程为只在最后一层施工时触发,而不必知道 A 类扩展的深度?

object LearnDelayedInit extends App {

  class A extends DelayedInit {
    def delayedInit(x: => Unit) {
      x  // call constructor code
      println("delayed init called")
    }
  }

  class B extends A {        
    println("Hello from B")    
  }

  class C extends B {    
    println("hello from C")
  }

  val c = new C    
}

输出:

Hello from B    
delayed init called    
hello from C    
delayed init called
4

2 回答 2

3

如果您将层次结构从特征中取出,并且仅将叶子类型作为类,您将获得您想要的行为:

object LearnDelayedInit extends App {

  trait A extends DelayedInit {
    def delayedInit(x: => Unit) {
      x  //call constructor code
      println("delayed init called")
    }
  }

  trait B extends A {
    println("Hello from B")
  }

  class C extends B {
    println("hello from C")
  }

  val c = new C
}

只有类的初始化代码被包装并传递给delayedInit,trait 的初始化代码像往常一样在构造函数中运行。

于 2013-09-03T02:30:22.133 回答
1

干得好。

未来的东西只是为了天赋。

基本思想是在初始化器中或任何底层类中val done只初始化一次。C

我想您已经阅读了The One Question FAQ中的一个问题。

object Test extends App {

  import java.util.concurrent.{ CountDownLatch => Latch }

  trait FutureInit {
    import concurrent._
    import ExecutionContext.Implicits._
    private var fs = future(())
    def done: Boolean
    val latch = new Latch(1)
    def delayedInit(x: => Unit) {
      fs = fs andThen {
        case _ =>
          x
          if (done) { println("All done!") ; latch.countDown() }
      }
    }
  }

  class A extends DelayedInit with FutureInit {
    println("Hello from A")
    Thread sleep 500L
    override val done = true
  }

  class B extends A {
    println("Hello from B")
    Thread sleep 500L
    override val done = true
  }

  class C extends B {
    println("hello from C")
    Thread sleep 500L
    override val done = true
  }

  val c = new C
  c.latch.await()
  println("Good bye.")

  val b = new B
  b.latch.await()
  println("That's all, folks. Go home.")
}
于 2013-09-03T06:34:08.147 回答