Scala中Future的返回值

时间:2015-07-19 14:11:08

标签: scala future

我有以下功能:

  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?

1 个答案:

答案 0 :(得分:2)

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

您正在使用Future.traverse并行查找可能的方法,因此您会得到Future[...]。您建议使用onSuccessList[List[Position]]返回Future,但使用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)
  }