相当于Scala中的c++函数中的静态变量
Scala equivalent of C++ static variable in a function
我是Scala新手,偶然发现了以下问题:
void foo()
{
static int x = 5;
x++;
printf("%d", x);
}
编辑:我想实现的是一种函数调用计数器-我想检查我的函数已经执行了多少次,并在同一时间限制这个计数器的可见性,这样它就不能从外部修改
下面是一段具有类似效果的代码:
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++的局部静态变量。在Scala中,作用域规则比c++或Java更加一致——在块中定义的内容,在块退出时将超出作用域。正如其他人所指出的,局部静态变量会产生副作用,这在函数式编程中是不可取的。
Scala,作为一种OO/函数式的混合语言,使命令式风格的编写成为可能,但更喜欢并鼓励函数式风格(例如,通过将不可变集合作为默认选择)。局部静态变量,除了表示本身的副作用外,在Java中也不存在,这是在Scala中不提供它们的另一个原因。
在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
}
然后在方法中:
def foo():Unit
{
object x extends StaticLocal( 5 )
x += 1
println( x )
}
这将像在c++中一样工作,包括当方法或所属类实例超出作用域时(尽管有性能损失)。不是线程安全的
相关文章:
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 模板基类中的静态变量
- 类和静态变量
- 不同作用域中的静态变量和全局变量
- 静态变量声明和定义
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 在类中继承静态变量?
- "local scope"中的 C++ 初始化静态变量
- 使用静态变量的递归调用的不同输出
- 复制文件流C++静态变量
- 跨模板化函数编译的静态变量
- C++编译器是否优化了顺序静态变量读取?
- C++,每个循环初始化一个新的静态变量
- (为什么)我们可以在初始化中将非静态类成员分配给静态变量吗?
- 这些语句是否等效(静态变量、常量变量和泛型)
- 程序如何知道静态变量是否需要初始化?
- 类外的静态变量实例化
- 无法解析静态变量
- 函数局部静态变量:从性能角度来看的优点/缺点
- 访问从 CPP 文件到其他头文件的静态变量