這不是真的回答你的問題,而且我討厭人們這樣做,但我仍然會這樣做。我認爲最好的迴應是:懶惰的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] = [email protected]
scala> optionalSubsystem.toOption.isDefined
res1: Boolean = false
scala> optionalSubsystem()
res2: java.lang.String = a
scala> optionalSubsystem.toOption.isDefined
res12: Boolean = true
編輯 - 這是另一個版本的一些修改感謝托馬斯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
}
這可以讓你寫lazily { ... }
而不是new Lazy { ... }
和optionalSubsystem
而不是optionalSubsystem()
。
scala> import Lazy._
import Lazy._
scala> val optionalSubsystem = lazily { "a" }
optionalSubsystem: Lazy[String] = [email protected]
scala> optionalSubsystem.isEvaluated
res0: Boolean = false
scala> optionalSubsystem: String
res1: String = a
scala> optionalSubsystem.isEvaluated
res2: Boolean = true
不,但是什麼決定了optionalSubsystem是否會被提出?它是運行時信息嗎?或編譯時信息? – stew
所有運行時。我找到了一種方法:'optionalSubsystem'有一個副作用 - 它引導一個演員。我檢查了副作用,直到這個答案更好。 –
「我啓動了一位阿卡演員,如果演員啓動了,我想監督它」。這個用例應該在問題中說明,如果這是你真正想知道的。 –