Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 隐式变量与未来_Scala - Fatal编程技术网

Scala 隐式变量与未来

Scala 隐式变量与未来,scala,Scala,我在使用隐式var和futures时遇到了一个问题。假设以下场景: object ImplicitMess extends App { implicit var curStr = "Initial Value" def useImplicit(implicit str: String) = { println(str) str.length } useImplicit val ftr = future { Thread.sleep(1000)

我在使用隐式var和futures时遇到了一个问题。假设以下场景:

object ImplicitMess extends App {

  implicit var curStr = "Initial Value"

  def useImplicit(implicit str: String) = {
    println(str)
    str.length
  }

  useImplicit

  val ftr = future {
    Thread.sleep(1000)
    useImplicit
  }

  curStr = "Modified Value"

  Await.ready(ftr, 2.seconds)

}
在创建未来时,隐式值是“初始值”,但在实际执行时,值是“修改值”,这不是期望的行为。 这是因为未来主体引用的是var,而不是当前值

因此,我提出的第一个解决方案是在一个块内捕获val中的var值,认为这将限定隐式closer的范围并解决歧义。但由于“不明确的隐式值”错误,它甚至无法编译

所以,我希望有一种方法来包装异步代码(任何期货操作),在定义异步代码时使用固定的隐式值,而不是在计算异步代码时

对于一个库来说,这些示例是问题的一个简化版本,所以我需要这样做有两个原因:1)为了实现所需的行为。2) 解除用户了解所有这些复杂性的责任

...
  val ftr = fixImplicit {
    // All within this block will use the current value of the implicit var
    future {
      Thread.sleep(1000)
      useImplicit
    }
  }
...
你认为这可能吗?
多谢各位

[已编辑]为所有对var使用感到恐惧的人添加一些上下文

我需要它来改进我的一个项目,即akka context actor(),它是关于在参与者之间传播公共上下文,避免使用方面库。因此,主要需求之一是透明地执行,而不显式地传递隐式

我在很大程度上依赖于隐式转换来包装和解包消息,除了在actor中的var中包含上下文以使其在receive中可用之外,我没有其他选择。你可以看看代码,看看我是怎么做的

再次感谢

加斯顿。

@ktonga

首先,您确定需要使用VAR吗?VAL更为惯用

如果您需要在将来完成之前访问var的值,您可以只保存一个副本,然后显式使用该参数:

  val ftr = future {
    val saved = curStr
    Thread.sleep(1000)
    useImplicit(saved)
  }

首先,您确定需要使用VAR吗?VAL更为惯用

如果您需要在将来完成之前访问var的值,您可以只保存一个副本,然后显式使用该参数:

  val ftr = future {
    val saved = curStr
    Thread.sleep(1000)
    useImplicit(saved)
  }

另一个答案是,您必须隐藏隐式

scala> :pa
// Entering paste mode (ctrl-D to finish)

object ImplicitMess extends App {

  implicit var curStr = "Initial Value"

  def useImplicit(implicit str: String) = {
    println(str)
    str.length
  }

  useImplicit

  val ftr = {
    implicit val curStr = ImplicitMess.curStr
    future {
    Thread.sleep(1000)
    useImplicit
  }}
  curStr = "Modified Value"

  Await.ready(ftr, 2.seconds)

}

// Exiting paste mode, now interpreting.

warning: there were 1 deprecation warning(s); re-run with -deprecation for details
defined object ImplicitMess

scala> ImplicitMess main null
Initial Value
Initial Value
当然,关于VAL的建议仍然适用

更新:


如果我们谈论的是,那么我认为可以解决这个问题。

另一个答案是,你必须隐藏隐含的信息

scala> :pa
// Entering paste mode (ctrl-D to finish)

object ImplicitMess extends App {

  implicit var curStr = "Initial Value"

  def useImplicit(implicit str: String) = {
    println(str)
    str.length
  }

  useImplicit

  val ftr = {
    implicit val curStr = ImplicitMess.curStr
    future {
    Thread.sleep(1000)
    useImplicit
  }}
  curStr = "Modified Value"

  Await.ready(ftr, 2.seconds)

}

// Exiting paste mode, now interpreting.

warning: there were 1 deprecation warning(s); re-run with -deprecation for details
defined object ImplicitMess

scala> ImplicitMess main null
Initial Value
Initial Value
当然,关于VAL的建议仍然适用

更新:


如果我们讨论的是隐式VAR,那么我认为它解决了这一问题。

我从未意识到隐式VAR甚至是可能的,在Scala中也没有比这更可怕的了。你绝对确定你必须这样做吗?var capture@TravisBrown你的隐式执行上下文应该完全是一个var,所以你可以随时切换它!“嗨,特拉维斯布朗,你们用“任何更可怕的事情”让我大笑起来。我确信第一个答案或评论是警告我使用vars。我知道这很糟糕。我对这个问题进行了编辑,添加了更多的上下文。我从未意识到隐式变量甚至是可能的,在Scala中,我想不出有什么比这更可怕的了。你绝对确定你必须这样做吗?var capture@TravisBrown你的隐式执行上下文应该完全是一个var,所以你可以随时切换它!“嗨,特拉维斯布朗,你们用“任何更可怕的事情”让我大笑起来。我确信第一个答案或评论是警告我使用vars。我知道这很糟糕。我编辑了这个问题以添加更多的上下文。谢谢@Gangstead,我知道这个解决方案,但遗憾的是,显式传递值不是一个选项。我编辑这个问题是为了解释原因。谢谢@Gangstead,我知道这个解决方案,但遗憾的是,显式传递值不是一个选项。我编辑这个问题是为了解释原因。谢谢@som snytt,这似乎是一个有效的解决方案,正如预期的那样。最好不要把这个责任放在lib的用户端(问题编辑),但到目前为止这是可以接受的。谢谢@som snytt,这似乎是一个有效的解决方案,正如预期的那样工作。最好不要把这个责任放在lib的用户端(问题编辑),但到目前为止这是可以接受的。