Return 来自 Scala 中 Future 的值

Return value from Future in Scala

我有以下功能:

  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))
      }
    }
  }

}

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

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

return 正确值的可能性有多大?我在哪里做这个?在 onSuccess?

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

您正在使用 Future.traverse 并行查找可能的方法,因此您得到 Future[...] 作为结果。您建议使用 onSuccess 到 return 来自 FutureList[List[Position]],但是使用 onSuccess 您实际上注册了一个回调函数,它将在 Future成功结束。由于回调函数将独立于您的 getWayDepthFirst 函数执行,因此您不能 return 此回调函数内部的任何内容。

解决方案是将 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)
  }