C++ C+的Scala等价物+;函数中的静态变量
我是Scala的新手,偶然发现以下问题: 什么是函数的静态变量的Scala等价物?C++ C+的Scala等价物+;函数中的静态变量,c++,scala,static-variables,C++,Scala,Static Variables,我是Scala的新手,偶然发现以下问题: 什么是函数的静态变量的Scala等价物? void foo() { static int x = 5; x++; printf("%d", x); } 编辑: 我想实现的是一种函数调用计数器——我想检查函数的执行次数,同时限制这个计数器的可见性,使它不能从外部修改。< /P> < P>斯卡拉没有等价于C++的局部静态变量。在斯卡拉,范围规则比C++或java更一致——在块中定义的内容在退出块时超出范围。正如其他人所指出的,局部
void foo()
{
static int x = 5;
x++;
printf("%d", x);
}
编辑:
我想实现的是一种函数调用计数器——我想检查函数的执行次数,同时限制这个计数器的可见性,使它不能从外部修改。< /P> < P>斯卡拉没有等价于C++的局部静态变量。在斯卡拉,范围规则比C++或java更一致——在块中定义的内容在退出块时超出范围。正如其他人所指出的,局部静态变量会产生副作用,这在函数式编程中是不可取的
Scala是一种混合的OO/函数式语言,可以使用命令式风格编写,但更喜欢并鼓励使用函数式风格(例如,通过将不可变集合作为默认选择)。除了表示副作用本身之外,Java中也没有局部静态变量,这也是Scala中不提供它们的另一个原因。下面是一段具有类似效果的代码:
scala> object f extends Function0[Unit] {
| var x = 0;
| def apply = {
| x = x + 1;
| println(x);
| }
| }
defined module f
scala> f()
1
scala> f()
2
尽管我必须强调,这是一种非常糟糕的做法,因为它会导致死亡
如果你真的需要这种行为,考虑一下:
type State = Int
def f(state: State) = {
val newState = state + 1
println(state);
newState;
}
在Scala中获得C++局部静态变量的等价性:
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
}
这将像C++一样工作,包括当方法或拥有类实例超出范围时(尽管还存在性能损失)。
不是线程安全的。您能描述一下为什么要将
x
设置为静态吗?可以从foo
外部访问它吗?foo
可能是递归的吗?我对C++不太熟悉,知道你的意图会让你更容易想出相应的Scala代码片段。纯函数编程避免了这种可变的变量,因为它导致了一个不透明的函数。C++侧:这被称为局部静态,该变量是全局变量,因为整个程序中只存在一个实例,但其可见性(词法范围)仅限于函数体。这个习语可以用来实现单例,例如,这个副本(第一个例子)实际上更像是C++的函子,但是它确实表现为“代码> f*())/Case>有一个本地静态变量。这不一定要杀死引用的透明度。我想到了回忆录。
def foo():Unit
{
object x extends StaticLocal( 5 )
x += 1
println( x )
}