Scala Mutable Option?

问题描述:

我想是这样的:Scala Mutable Option?

​​

我不是在寻找一个通用的HashMap基于记忆化like this。我试图用一个var Option[A]实现它,但它看上去并不十分地道的对我说:

private var cachedResponse: Option[A] = None 

def get: A = cachedResponse getOrElse { 
cachedResponse = Option(db.findModel()) 
cachedResponse.get 
} 

def update: Unit = { 
    db.updateModel 
    cachedResponse = None 
} 
+3

一个快速的谷歌搜索发现这个实现,看起来像你想要的...:http://blog.adamdklein.com/?p=689 – experquisite 2014-10-20 21:59:09

没有一个内置的标准库。

使用包含一个不可变的Optionvar是这样做的惯用方法(假设您不能重写它以根本不使用状态)。

否则,你应该建立自己的。下面是一个实现的核心:

class MutableOpt[A] { 
    private[this] var myValue: A = _ 
    private[this] var loaded = false 
    private def valueEquals(o: Any) = myValue == o 
    def get = if (loaded) myValue else throw new NoSuchElementException("MutableOpt") 
    def set(a: A): this.type = { loaded = true; myValue = a; this } 
    def getOrSet(a: => A): A = { 
    if (!loaded) { 
     myValue = a 
     loaded = true 
    } 
    myValue 
    } 
    def isEmpty = !loaded 
    def nonEmpty = loaded 
    def foreach[U](f: A => U): Unit = if (loaded) f(myValue) 
    def transform(f: A => A): this.type = { if (loaded) myValue = f(myValue); this } 
    def clear(): this.type = { loaded = false; this } 
    def toOption = if (loaded) Some(myValue) else None 
    override def toString = if (loaded) "MutableOpt("+myValue.toString+")" else "MutableOpt()" 
    override def hashCode = if (loaded) myValue.hashCode else 1751 
    override def equals(o: Any) = o match { 
    case m: MutableOpt[_] => 
     (isEmpty && m.isEmpty) || (nonEmpty && m.nonEmpty && m.valueEquals(myValue)) 
    case _ => false 
    } 
} 
object MutableOpt { 
    def from[A](o: Option[A]) = { 
    val m = new MutableOpt[A] 
    o match { 
     case Some(a) => m set a 
     case _ => 
    } 
    m 
    } 
} 

如果使用REPL与:paste一起定义。

+0

LGTM。感谢分享。但是,在多线程环境中getrSet中可能存在一些竞争条件。 – pathikrit 2014-10-21 03:19:47

+0

没错,这正是不可变性与可变性之间的优势之一。 – 2014-10-21 04:46:22

+0

@wrick - 绝对,就像几乎所有的东西都是可变的。你可以使所有的操作都是原子的,但是性能会受到影响。 – 2014-10-21 08:48:18