【问题标题】:Scala: multiple return statement in method that returns Future[Boolean]Scala:返回Future [Boolean]的方法中的多个return语句
【发布时间】:2016-11-04 19:31:35
【问题描述】:

我想做这样的事情。

 def foo(s : String): Future[Boolean] = Future {
    val a = someLongRunningMethod

    if(!a)
      return false or throw some exception // what should i return 

    //do some more thing

    val b= someMoreLongRunningMethod
    if(b)
      return true

    return false
  }

但不能将 return 与布尔值一起使用。我收到类型不匹配错误。

Error:(32, 12) type mismatch;
 found   : Boolean(false)
 required: scala.concurrent.Future[Boolean]
    return false

我是 Scala 新手。我正在使用 foo 方法。我不确定这是否是使用它的最佳方式。请建议我应该如何实现它?

val r = foo("Nishant")
r.onComplete {
  case Success(result) => {
    //Do something with my list
    println("success: " + result)
  }
  case Failure(exception) => {
    //Do something with my error
    println("failure")
  }
}
val re = Await.result(r, 10 second)

【问题讨论】:

  • 您需要先阅读有关Future 类型如何工作的教程(顺便说一句,使用这样的返回不是Scala idomatic)
  • 我阅读了一些教程,但它们都有单个 if/else 块的示例。你能推荐一些好的教程吗

标签: scala concurrency future


【解决方案1】:

在 Scala 中,块中的最后一个表达式是代码块或函数的返回值。关键字 return 在 scala 中是可选的。

请注意,只有当一个任务返回 true 时,我们才会运行第二个任务。如果第一个任务返回 false,那么我们就完成了。这意味着第一个任务对于我们作为决策者的计算来说非常重要。

您的版本已修改:

  def longRunning1: Boolean = ???
  def longRunning2: Boolean = ???

  import scala.concurrent.ExecutionContext.Implicits.global

  def foo(s : String): Future[Boolean] = Future {
    val a: Boolean = longRunning1
    if(a) {
      val b: Boolean = longRunning2
      b
    } else false
  }

版本 1:

同时运行期货(计算或长期运行方法)并稍后选择结果。如果我们考虑或想要第一次计算的结果,这里我们丢弃第二次计算的结果。

import scala.concurrent.ExecutionContext.Implicits.global

  def foo(s: String): Future[Boolean] = {

    val f1 = Future {
      Thread.sleep(20000) //Just to simulate long running task
      Random.nextBoolean()
    }

    val f2 = Future {
      Thread.sleep(1000) //Just to simulate long running task
      Random.nextBoolean()
    }

    (f1 zip f2) map {
      case (false, _) => false
      case (true, f2Result) => f2Result
      case _ => false
    }

  }

版本 2:

运行第一种方法,然后根据第一种方法的结果尝试依次运行第二种方法。使用 map 链接计算。

import scala.concurrent.ExecutionContext.Implicits.global

  def foo(s: String): Future[Boolean] = {

    val f1 = Future {
      Thread.sleep(20000) //Just to simulate long running task
      Random.nextBoolean()
    }

    f1.map { result =>
      if (result) result
      else {
        Thread.sleep(1000) //Just to simulate long running task
        Random.nextBoolean()
      }
    }

  }

【讨论】:

  • 在版本 2 中。如果两个 logRunningTash 都可以抛出,如何处理异常,以及当两个任务都依赖时哪个更好,即第二个需要来自第一个的输入?
  • @NishantKumar 让我用例外情况更新问题
  • @NishantKumar 版本:2 比版本 1 好。从异常的角度来看,v1 和 v2 都很好
猜你喜欢
  • 2019-04-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 2021-02-06
  • 2011-04-15
  • 2023-02-22
  • 2016-06-12
  • 2019-05-09
相关资源
最近更新 更多