内容简介:Scala 的
scala.util.DynamicVariable
,这个类有点类似于 java 里面 ThreadLocal
,适合用来保存和传递上下文(Context)相关的信息。
Scala 的 官方文档 是这么介绍的:
DynamicVariables
提供了一种绑定机制,即变量的当前值是通过动态范围来查找的,但是对变量自身的访问是在静态范围里的。
这句话看着挺抽象的。简单的说,就和类名的含义一致,变量的值是动态获取的。使用 value
方法可以获取到当前的值。通过 withValue
方法设置新的值,但是这个新设置的值只有在 withValue
方法的第二个参数,一个无参数的闭包,执行的时候时候有效。一旦第二个参数执行完毕后,变量的值重新回到以前。类似于一个栈。
val hello = new DynamicVariable[String]("hello")
println(hello.value)
//hello
hello.withValue("world") {
println(hello.value)
}
//world
println(hello.value)
//hello
Each thread gets its own stack of bindings. When a new thread is created, the DynamicVariable gets a copy of the stack of bindings from the parent thread, and from then on the bindings for the new thread are independent of those for the original thread.
在 withValue
中创建一个新的线程,该线程从 DynamicVariable
中取出当前绑定的值,此后该值和父线程里面的绑定值就再无关联了。
实际上,从 DynamicVariable
的源码来看,就是基于 InheritableThreadLocal
实现的。代码也并不复杂:
class DynamicVariable[T](init: T) {
private val tl = new InheritableThreadLocal[T] {
override def initialValue = init.asInstanceOf[T with AnyRef]
}
/** Retrieve the current value */
def value: T = tl.get.asInstanceOf[T]
/** Set the value of the variable while executing the specified
* thunk.
*
* @param newval The value to which to set the variable
* @param thunk The code to evaluate under the new setting
*/
def withValue[S](newval: T)(thunk: => S): S = {
val oldval = value
tl set newval
try thunk
finally tl set oldval
}
/** Change the currently bound value, discarding the old value.
* Usually withValue() gives better semantics.
*/
def value_=(newval: T) = tl set newval
override def toString: String = "DynamicVariable(" + value + ")"
}
这个问题
很好地说明了我们应该怎么用 DynamicVariable
。
It’s a non-intrusive way to store and pass around context(thread)-specific information.
其中一个答案里提到 Concole.println
这个方法的实现,很有意思。
-
println()即Console.println() -
Console.println()是 基于DynamicVariable[PrintStream], 默认值是java.lang.System.out -
Console提供了一个withOut,实际上就是对内部动态变量的withValue方法的封装
def noisy() { println("robot human robot human") }
noisy() // prints to stdout
val ps = new java.io.PrintStream("/tmp/mylog")
scala.Console.withOut(ps) { noisy() } // output now goes to /tmp/mylog file
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
MATLAB高效编程技巧与应用
吴鹏 / 北京航空航天大学 / 2010-6 / 39.00元
《MATLAB高效编程技巧与应用:25个案例分析》是作者八年MATLAB使用经验的总结,精心设计的所有案例均来自于国内各大MATLAB技术论坛网友的切身需求,其中不少案例涉及的内容和求解方法在国内现已出版的MATLAB书籍中鲜有介绍。 《MATLAB高效编程技巧与应用:25个案例分析》首先针对MATLAB新版本特有的一些编程思想、高效的编程方法、新技术进行了较为详细的讨论,在此基础上,以大量......一起来看看 《MATLAB高效编程技巧与应用》 这本书的介绍吧!