scala App类DelayedInit钩子

时间:2013-11-17 04:25:14

标签: scala

  trait App extends DelayedInit {
  //...
  private val initCode = new ListBuffer[() => Unit]

  /** The init hook. This saves all initialization code for execution within `main`.
   *  This method is normally never called directly from user code.
   *  Instead it is called as compiler-generated code for those classes and objects
   *  (but not traits) that inherit from the `DelayedInit` trait and that do not
   *  themselves define a `delayedInit` method.
   *  @param body the initialization code to be stored for later execution
   */
  override def delayedInit(body: => Unit) {
    initCode += (() => body)
  }
  //...
}

object CircuitMain extends App {
  // You can write tests either here, or better in the test class CircuitSuite.
  Circuit.andGateExample //line in question ?
}

Related Post why-if-i-extend-the-app-trait-in-scala -i-override-the-main-method

我可以看到在评论中它说它将由编译器生成的代码调用 从相关帖子中可以看出,scala编译器会对 DelayedInit 做一些特殊的事情,是什么让这个 DelayedInit 特性如此特别?它是语言相关的功能吗?或者我们也可以对其他特征做类似的事情?如果是,那该怎么做。

1 个答案:

答案 0 :(得分:6)

前几天我在琢磨这个......

是的,这是一种特定于语言的功能 - 请参阅Scala语言规范中的第5.1节“延迟初始化”: http://www.scala-lang.org/docu/files/ScalaReference.pdf

您还可以确认此检查编译器源代码: https://github.com/scala/scala/blob/946b76ad8b31b1fd74e2f8e1972c4a9159ac690a/src/reflect/scala/reflect/internal/StdNames.scala

// Compiler utilized names
...
val delayedInit: NameType          = "delayedInit"
val delayedInitArg: NameType       = "delayedInit$body"

还有: https://github.com/scala/scala/blob/96df73d994097e3318d003ddef00194b711289a3/src/reflect/scala/reflect/internal/Definitions.scala

// classes with special meanings
lazy val StringAddClass             = requiredClass[scala.runtime.StringAdd]
lazy val ScalaNumberClass           = requiredClass[scala.math.ScalaNumber]
lazy val TraitSetterAnnotationClass = requiredClass[scala.runtime.TraitSetter]
lazy val DelayedInitClass           = requiredClass[scala.DelayedInit]
  def delayedInitMethod = getMemberMethod(DelayedInitClass, nme.delayedInit)