内容简介: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
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
编译原理
Alfred V. Aho、Monica S.Lam、Ravi Sethi、Jeffrey D. Ullman / 赵建华、郑滔、戴新宇 / 机械工业出版社 / 2008年12月 / 89.00元
本书全面、深入地探讨了编译器设计方面的重要主题,包括词法分析、语法分析、语法制导定义和语法制导翻译、运行时刻环境、目标代码生成、代码优化技术、并行性检测以及过程间分析技术,并在相关章节中给出大量的实例。与上一版相比,本书进行了全面的修订,涵盖了编译器开发方面的最新进展。每章中都提供了大量的系统及参考文献。 本书是编译原理课程方面的经典教材,内容丰富,适合作为高等院校计算机及相关专业本科生及研......一起来看看 《编译原理》 这本书的介绍吧!