【问题标题】:Return value from Future in ScalaScala中Future的返回值
【发布时间】:2015-07-20 04:16:21
【问题描述】:

我有以下功能:

  def getWayDepthFirst(maze: Maze, position: Position, way: List[Position]): List[List[Position]] = {
if (!canWalkOnCell(maze, position)) {
  Nil

} else {

  if (isExit(position, maze)) {
    List(position :: way)
  } else {

    val explorationArea: List[Position] = List(position.north, position.east, position.south, position.west) filter (x => !way.contains(x) && canWalkOnCell(maze, x))
    if (explorationArea.size > 1) {



    val possibleWays: Future[List[List[List[Position]]]] = Future.traverse(explorationArea)(notYetVisitedPosition => Future(getWayDepthFirst(maze, notYetVisitedPosition, position :: way)))

//        possibleWays.onSucces()

    } else {
      explorationArea.flatMap {
        (
          notYetVisitedPosition =>
            getWayDepthFirst(maze, notYetVisitedPosition, position :: way))
      }
    }
  }

}

它应该能找到穿过迷宫的所有方法。如果有两种或多种可能的搜索方式,那么以后应该处理其中的每一种。

现在我的问题是如何返回这个结果。使用 Future.traverse,我最终得到了 Future[List[List[List[Position]]]],但我需要的是 List[List[Position]]

返回正确值的可能性是什么?我在哪里做这个?在 onSuccess 中?

【问题讨论】:

    标签: scala future


    【解决方案1】:

    Zernike 建议future.map(_.flatten) 是正确的,但这会给你Future[List[List[Position]]] 而不是List[List[Position]]

    您正在使用Future.traverse 并行查找可能的方法,因此您得到Future[...]。您建议使用onSuccessFuture 返回List[List[Position]],但使用onSuccess 您实际上注册了一个回调函数,该函数将在Future 成功结束时执行。由于回调函数将独立于您的getWayDepthFirst 函数执行,因此您不能从该回调函数中返回任何内容。

    解决方案是将getWayDepthFirst 的结果类型更改为Future[List[List[Position]]]

    这看起来像这样:

    def getWayDepthFirst(
      maze: Maze, position: Position, way: List[Position]
    ): Future[List[List[Position]]] = 
      if (! canWalkOnCell(maze, position)) {
        Future.successful(Nil)
      } else if (isExit(position, maze)) {
        Future.successful(List(position :: way))
      } else {
        val positions = List(position.north, position.east, position.south, position.west)
        val explorationArea = positions filter (x => 
          !way.contains(x) && canWalkOnCell(maze, x)
        )
        Future.traverse(explorationArea)( notYetVisitedPosition => 
          getWayDepthFirst(maze, notYetVisitedPosition, position :: way)
        ).map(_.flatten)
      }
    

    【讨论】:

    • 谢谢,所以我会处理我第一次调用此方法的 onSuccess。尽管如此,我仍然遇到错误。 type mismatch; found : scala.concurrent.Future[List[List[Position]]] required: scala.concurrent.Future[List[Position]] 在这条线上 getWayDepthFirst(maze, notYetVisitedPosition, position :: way)) ).map(_.flatten)
    • 好像刚刚在 ) 地图前面太多了(_.flatten)
    • 你是对的,我已经从代码中删除了括号。您可以在 Scala website 上找到有关使用 Future 的更多信息
    • 可以使用scalaz的traverseM来代替.traverse(...).map(_.flatten)
    猜你喜欢
    • 2017-08-02
    • 2023-03-06
    • 2013-01-24
    • 2016-08-01
    • 2016-06-03
    • 2012-12-18
    • 2020-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多