当前位置: 首页 > 知识库问答 >
问题:

在Future的成功调用中变量的作用域发生了变化

焦博实
2023-03-14

我需要取回一个在未来的onSuccess块中被改变的变量。这是我的示例代码。

def futureFunction(arg:Any):Any = { 
  implicit val timeout = Timeout(10 seconds) 
  var ret:Any = None
  val f: Future[Any] = someActor ? arg
    f.onSuccess {
      case a:String => {
        ret = 1 
        println(ret) //prints "1" 
      }
      case a:Int => { 
        ret = 2 
        println(ret) //prints "2"
      }
    }
  ret //returns None
  }

ret返回为无,不会变为1,或2。那么这是否意味着onSuccess块中变量ret的值无法返回?然而,这似乎奏效了:

var a : Any = None

{
  a = 1
  println("inside "+ a ) //prints "inside 1"
}

println(a)   // prints "1"

我可以在未来的onSuccess块中做什么,以便根据未来的结果是整数还是字符串,将< code>ret的值返回为< code>1或< code>2?在这种情况下,scala的作用域规则是什么?(我用的是akka)。感谢任何帮助。谢了。

共有2个答案

笪昌翰
2023-03-14
匿名用户

FutureFunction中,reton成功处理程序运行之前返回。当这种情况发生时,ret将变成12,但那时已经太晚了。

您要使用的是< code>Future.map

someActor ? arg map {
  case a:String => 1
  case a:Int => 2 
}

请注意,< code>futureFunction要么必须返回一个< code>Future,要么必须在函数内部调用< code>Await.result来阻塞,直到结果可用。

况谦
2023-03-14

这里的问题不是范围,而是时机。

  1. 首先,将ret初始化为None
  2. 然后,您将消息arg发送到someActor,该消息返回一个未来
  3. 然后,设置一个函数,在将来完成时调用,如果一切顺利,该函数将在将来的某个时间点为ret赋值1或2
  4. 最后,立即返回ret的值,该值仍然是None
  5. 在未来的某个时刻,未来完成,您的onSuccess函数运行,更改ret的值,然后打印它。但当然,这不能返回到时间上并更改先前已返回的值

因此,为了回答您的问题,您在onResess中无法做任何事情来回到过去并更改已经返回的值。不过有两种选择。一种选择是阻止直到未来完成,然后确定是返回1还是2。另一种是返回一个Future[Int],以便调用者可以决定是否要阻止结果。它的代码实际上比您拥有的更简单:

def futureFunction(arg:Any):Future[Int] = { implicit val timeout = Timeout(10 seconds) val f: Future[Any] = someActor ? arg f.map { case a:String =

如果您确实需要阻塞,您可以使用Await.result,根据您要阻塞的位置,可以在FutureFunction内部或外部使用。

 类似资料:
  • 主要内容:成员变量,局部变量变量的作用域规定了变量所能使用的范围,只有在作用域范围内变量才能被使用。根据变量声明地点的不同,变量的作用域也不同。 根据作用域的不同,一般将变量分为不同的类型:成员变量和局部变量。下面对这几种变量进行详细说明。 成员变量 Java 的成员变量有两种,分别是全局变量和静态变量(类变量)。定义在方法体和语句块之外,不属于任何一个方法,作用域是整个类。 名称 修饰 访问 生命周期 全局变量(实例变量)

  • 4.2.5 变量的作用域 程序中的变量都有自己的作用域(scope,或称辖域),即程序的一部分区域,在其中可以访问该变量。一个变量只有在它的作用域中才有定义,才能被访问。 局部变量 在一个函数中定义的变量称为局部变量(local variable),因为它们的作用域局限于该 函数的函数体,在函数外部是没有定义的。例如: >>> def func(x,y): z = x + y pr

  • Less 中的变量和其他编程语言一样,可以实现值的复用,同样它也有作用域(scope)。简单的讲,变量作用域就是局部变量和全局变量的概念。 Less 中,变量作用域采用的是就近原则,换句话说,就是先查找自己有没有这个变量,如果有,就取自己的变量,如果没有,就查找父元素,依此类推。先看一个简单的例子,Less 文件如下: @width : 20px;  #homeDiv  {    @width

  • 变量作用域 变量的作用域值的是变量的生命周期和作用范围(全局与局部作用域的区别)。 作用域介绍 静态作用域 静态作用域有称为词法作用域,即指其在编译的阶段就可以决定变量的引用。静态作用域只更变量定义的位置有关与代码执行的顺序无关。 var x = 0; function foo() { alert(x); } function bar() { var x = 20; foo(); }

  • 任何编程中的范围都是程序的一个区域,其中定义的变量可以存在,并且超出该变量无法访问。 有三个地方,其中变量可以用Pascal编程语言声明 - 在子程序或块中,称为局部变量 在所有子程序之外,称为全局变量 在子程序参数的定义中称为形式参数 让我们解释什么是local和global变量和形式参数。 局部变量 (Local Variables) 在子程序或块内声明的变量称为局部变量。 它们只能由子程序或

  • 如果你之前用过像Python或者Ruby之类的动态语言,现在你可能已经熟悉了Vim脚本的变量。你会发现Vim变量的大部分内容跟你想的一样,不过有一个东西可能会不同,那就是变量的作用域。 在两个分隔的窗口中分别打开两个不同的文件,然后在其中一个窗口中执行下面的命令: :::vim :let b:hello = "world" :echo b:hello 如你所愿,Vim会显示world。现在切换到