我们啥时候应该使用 scala.util.DynamicVariable?

Posted

技术标签:

【中文标题】我们啥时候应该使用 scala.util.DynamicVariable?【英文标题】:When we should use scala.util.DynamicVariable?我们什么时候应该使用 scala.util.DynamicVariable? 【发布时间】:2011-07-04 05:36:43 【问题描述】:

当我阅读scalatra的源代码时,我发现有一些代码:

protected val _response   = new DynamicVariable[HttpServletResponse](null)
protected val _request    = new DynamicVariable[HttpServletRequest](null)

有一个有趣的类名为DynamicVariable。我看过这个类的文档,但我不知道什么时候以及为什么我们应该使用它?它有一个通常使用的withValue()

如果我们不使用它,那么我们应该使用什么代码来解决它解决的问题?

(我是scala的新手,如果你能提供一些代码,那就太好了)

【问题讨论】:

scala-programming-language.1934581.n4.nabble.com/… 【参考方案1】:

DynamicVariable 是贷款和动态范围模式的实现。 DynamicVariable 的用例与 Java 中的 ThreadLocal 非常相似(事实上,DynamicVariable 在幕后使用 InheritableThreadLocal) - 当您需要在封闭范围内进行计算时使用它,每个线程都有自己的变量值副本:

dynamicVariable.withValue(value) valueInContext =>
  // value used in the context
 

鉴于DynamicVariable 使用可继承的ThreadLocal,变量的值将传递给上下文中生成的线程:

dynamicVariable.withValue(value) valueInContext =>
  spawn
    // value is passed to the spawned thread
  

DynamicVariable(和 ThreadLocal)在 Scalatra 中使用的原因与它在许多其他框架(Lift、Spring、Struts 等)中使用的原因相同 - 这是一种存储和传递上下文的非侵入式方式(线程)特定的信息。

制作 HttpServletResponseHttpServletRequest 动态变量(因此,绑定到处理请求的特定线程)只是在代码中的任何位置获取它们的最简单方法(不通过方法参数或以其他方式显式传递) .

【讨论】:

【参考方案2】:

Vasil 很好地回答了这个问题,但我将添加一个额外的简单示例,可能会进一步帮助理解。

假设我们必须使用一些使用 println() 的代码来写整个标准输出。我们希望将此输出转到日志文件,但我们无权访问源代码。

println() 使用 Console.println() Console.println()(幸运的是)是 based on 一个 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

【讨论】:

【参考方案3】:

这是一个最小的 sn-p:

val dyn = new DynamicVariable[String]("withoutValue")
def print=println(dyn.value)
print
dyn.withValue("withValue") 
  print

print

输出将是:

withoutValue
withValue
withoutValue

【讨论】:

以上是关于我们啥时候应该使用 scala.util.DynamicVariable?的主要内容,如果未能解决你的问题,请参考以下文章

我们啥时候应该使用 PreparedStatement 而不是 Statement?

我们啥时候应该使用 SNOWPIPE?

我们啥时候应该使用 save() 的高级参数?

我们啥时候应该使用 scala.util.DynamicVariable?

我们啥时候应该使用普通 BFS 而不是双向 BFS?

我们啥时候应该考虑使用私有或受保护?