Per ottenere l'equivalente di un C++ variabile statica locale a Scala:
import scala.collection.parallel.mutable
import scala.reflect._
import scala.reflect.runtime.universe._
object StaticLocal {
private val classes = new mutable.ParHashSet[String]
private val variables = new mutable.ParHashMap[String, AnyVal]
}
import Numeric._
class StaticLocal[T <: AnyVal](value:T)(implicit tag: TypeTag[T], num: Numeric[T]){
val name = this.getClass + "." + tag.toString() ;
private var inited = false
if (!inited) {
inited = true
if (!StaticLocal.classes.contains(name)) {
StaticLocal.classes += name
StaticLocal.variables += name -> value.asInstanceOf[AnyVal]
}
}
def get():T = {StaticLocal.variables.get(name) match { case x:Some[Int] => (x.get).asInstanceOf[T] ; case None => throw new Exception("Not found:" + name) }}
def set(value:AnyVal) { StaticLocal.variables.put(name, value)}
def +(v:StaticLocal[T]):T = { num.plus(this.get, v.get) }
def +(v:T):T = { num.plus(this.get, v) }
def +=(v:T):Unit = { set(num.plus(this.get, v)) }
def +=(v:StaticLocal[T]):Unit = { set(num.plus(this.get, v.get)) }
override def toString() = { get.toString}
implicit def StaticLocalWrapper(s: StaticLocal[T]):T = s.get
}
Poi nel metodo:
def foo():Unit
{
object x extends StaticLocal(5)
x += 1
println(x)
}
Funzionerà esattamente come in C++, anche quando il metodo o proprietario dell'istanza di classe non rientra nello scope (anche se w con una penalità di prestazioni). Non protetto da thread così com'è.
fonte
2015-11-20 08:57:49
Potresti descrivere perché fai 'x' statico? Vi si può accedere da fuori di 'foo'? 'Foo' può essere ricorsivo? Non ho molta familiarità con C++ e sapendo che la tua intenzione renderà più facile creare uno snippet di codice Scala corrispondente. –
La programmazione funzionale pura evita questo tipo di variabile mutabile perché porta a una funzione che non è "trasparente". – Mik378
Lato C++: questo è noto come statico locale, la variabile è * globale * in quanto esiste una sola istanza in tutto il programma, tuttavia la sua visibilità (ambito lessicale) è limitata al corpo della funzione. Questo idioma può essere usato per implementare singleton, per esempio. –