如何在不初始化的情况下检查是否初始化了lazy val?

Fra*_*eil 16 scala

是否有可能确定是否初始化了lazy val而没有初始化它?

object TheApp {
    lazy val optionalSubsystem = {
        // ...
        subsystem
    }

    def main(args: Array[String]) {
        bootSubsystemA(this)
        bootSubsystemB(this)

        if (/* optionalSubsystem is initialized */) {
            // more dependencies
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*tin 15

这不是你问题的真正答案,我讨厌人们这样做,但无论如何我都会这样做.我认为最好的回答是:懒惰的val不适合这个,所以定义一个支持你需要的类型.

你必须将变量称为optionalSubsystem()而不是optionalSubsystem,但这是一件好事,因为根据你想要的设计,获得那个参考是一个明显的副作用程序.

class Lazy[A](f: => A, private var option: Option[A] = None) {

  def apply(): A = option match {
    case Some(a) => a
    case None => val a = f; option = Some(a); a
  }

  def toOption: Option[A] = option

}

scala> val optionalSubsystem = new Lazy { "a" }
optionalSubsystem: Lazy[java.lang.String] = Lazy@1210267

scala> optionalSubsystem.toOption.isDefined
res1: Boolean = false

scala> optionalSubsystem()
res2: java.lang.String = a

scala> optionalSubsystem.toOption.isDefined
res12: Boolean = true
Run Code Online (Sandbox Code Playgroud)

编辑 - 由于Tomas Mikula,这是另一个修改和修改:

import scala.language.implicitConversions

object Lazy {

  def lazily[A](f: => A): Lazy[A] = new Lazy(f)

  implicit def evalLazy[A](l: Lazy[A]): A = l()

}

class Lazy[A] private(f: => A) {

  private var option: Option[A] = None

  def apply(): A = option match {
    case Some(a) => a
    case None => val a = f; option = Some(a); a
  }

  def isEvaluated: Boolean = option.isDefined

}
Run Code Online (Sandbox Code Playgroud)

这让你写lazily { ... },而不是new Lazy { ... }和,optionalSubsystem而不是optionalSubsystem().

scala> import Lazy._
import Lazy._

scala> val optionalSubsystem = lazily { "a" }
optionalSubsystem: Lazy[String] = Lazy@3d0d54

scala> optionalSubsystem.isEvaluated
res0: Boolean = false

scala> optionalSubsystem: String
res1: String = a

scala> optionalSubsystem.isEvaluated
res2: Boolean = true
Run Code Online (Sandbox Code Playgroud)