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

无法编译带有未来列表的代码

哈扬
2023-03-14

关于StackOverflow有一些关于如何处理期货列表的建议,但我想尝试我自己的方法。但是我无法编译以下代码

我有一份未来的清单。我想数一数他们中有多少人及格或不及格。我应该得到(2,1),我将其存储在一个元组中。我想采取的方法是遍历列表中的每个元素。列表的元素是Future[Int]。对于每个元素,我调用flatMap,它调用下一个递归循环(我假设如果调用flatMap,那么特定的未来将是成功的,因此我增加了传递计数)。类似地,我想在recover和increment fail count中调用下一个递归周期,但我在其中得到了编译错误。

import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success, Try}
import scala.concurrent.duration._
import scala.language.postfixOps

object ConcurrencyExample extends App {

  type pass = Int
  type fail = Int

  val time = System.currentTimeMillis()

//use recursion to process each Future in the list 
  def segregate(l:List[Future[Int]]):Future[Tuple2[pass,fail]] = {
    def go(l:List[Future[Int]],t:Tuple2[pass,fail]):Future[Tuple2[pass,fail]] = {
        l match {
          case Nil => Future{t}
            //l is List of Future[Int]. flatMap each successful Future 
            //recover each failed Future
          case l::ls => {
            l flatMap (x => go(ls, (t._1 + 1, t._2)))
              **l.recover({ case e => go(ls, (t._1 + 1, t._2))})**//I get error here
          }
        }
    }
    go(l,(0,0))
  }

//hardcoded future
  val futures2: List[Future[Int]] = List(Future {
    1
  }, Future {
    2
  }, Future {
    throw new Exception("error")
  })


  val result = segregate(futures2)
  result onComplete {
    case Success(v) => println("pp:" + v)
    case Failure(v) => println("fp:" + v)
  }

  Await.result(result,1000 millis)
}

共有2个答案

韶景曜
2023-03-14

如果你看一下: T](pf: PartialFunction[Throwable, U])(implcit在执行器:scala.concurrent.ExecutionContext):scala.concurrent.Future[U]"rel="no在执行器">文档,恢复的签名是:

def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U]

您在< code>l上调用的是< code>Future[Int]的< code>recover,因此< code>recover需要一个< code>U

但是,您正在再次调用go,其返回类型为Future[(通过,失败)]而不是

卢元龙
2023-03-14

@evan058关于恢复的签名是正确的。但是您可以通过将恢复更改为恢复来修复您的程序。

recoverWith要像flatMap要映射一样进行恢复。

以下是完整的解决方案(略有样式改进):

import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success, Try}
import scala.concurrent.duration._
import scala.language.postfixOps

object ConcurrencyExample extends App {

  type pass = Int
  type fail = Int

  val time = System.currentTimeMillis()

  //use recursion to process each Future in the list
  def segregate[T](fs:List[Future[T]]):Future[(pass,fail)] = {
    def go(fs:List[Future[T]],r:Future[(pass,fail)]):Future[(pass,fail)] = fs match {
      case Nil => r
      case l::ls =>
        val fx = l.transform({_ => (1, 0)}, identity).recoverWith[(pass,fail)]({case _: Exception => Future(0, 1) })
        for (x <- fx; t <- r; g <- go(ls, Future(t._1+x._1,t._2+x._2))) yield g
    }
    go(fs,Future((0,0)))
  }

  //hardcoded future
  val futures2 = List(Future(1), Future(2), Future(throw new Exception("error")))    

  val result = segregate(futures2)
  result onComplete {
    case Success(v) => println(s"successes: ${v._1}, failures: ${v._2}")
    case Failure(v) => v.printStackTrace()
  }

  Await.result(result,1000 millis)
}
 类似资料:
  • 我正在尝试学习java的这个新GWT部分。。。 我做了我的第一个简单的应用程序 我命名了 我的模块:-HelloWorld 我收到以下错误: 2014年4月18日下午4:00:53爪哇。util。首选项。WindowsPreferences警告:无法在根0x8000002处打开/创建prefs根节点Software\JavaSoft\prefs。Windows RegCreateKeyEx(…)返

  • 我使用了Jooq官方网站上的这个工具:https://github.com/etiennestuder/gradle-jooq-plugin从我的数据库生成代码。 但如果我设置

  • 我正在寻找一种将任意长度的期货列表转换为期货列表的方法。我使用的是Playframework,所以最终,我真正想要的是一个<code>未来〔结果〕,但为了让事情更简单,让我们说<code>将来〔List[Int]]通常的方法是使用<code>Future.sequence(…) 例如,执行以下操作不起作用: 我希望能够将1和3从那里拉出来,而不是只得到异常。我尝试将来使用<code>。折叠,但这显

  • 我想利用Tokio的运行时来处理可变数量的异步期货。由于在编译时期货的计数是未知的,因此 FuturesUnorderd 似乎是我的最佳选择(像 这样的宏需要在编译时指定你的分支;join_all可能是可能的,但是当顺序无关紧要时,文档建议“在很多情况下”FuturesUnordered)。 这个片段的逻辑是一个recv()循环,它被推送到期货桶中,应该一直运行。当新数据到达时,它的解析/处理也被

  • 问题内容: 以下代码给出了编译器错误 有时出于测试目的,希望防止某个方法被调用,因此一种快速执行此方法(而不是在使用 该方法的位置处将其注释掉)的方法是立即从该方法返回,以便该方法不执行任何操作。然后,我总是做些什么来解决编译器错误,这是 我很好奇,为什么会出现编译器错误?它会以某种方式破坏Java字节码,是为了保护程序员还是其他? 同样(这对我来说更有趣),如果将Java编译为字节码可以进行任何

  • 问题内容: 从一些类的源代码开始,我看到一些方法包含编译后的代码,在扩展之前,它们看起来像这样: 扩展该方法时,您可以看到其中的代码被写为注释。 请参阅以下方法之一: 我有兴趣进一步了解这些方法以及所使用的语言。 是否可以编写自己的编译代码? 问题答案: 也就是Java(或其他Java兼容语言,如注释所示)。 当给您一个jar文件(例如带有JDK / JRE的rt.jar)时,该文件已经被编译。高