将 Scala List[Either] 评估为布尔值

Evaluating a Scala List[Either] into a Boolean

我正在使用 scanamo 查询 dynamodb,我想做的就是检查该数据库是否确实存在。我并不真正关心我得到的记录,只是没有错误。对于查询部分,我使用的是:

trait DynamoTestTrait extends AbstractDynamoConfig {  def test(): Future[List[Either[DynamoReadError, T]]] =    ScanamoAsync.exec(client)table.consistently.limit(1).scan())}

那 return 是未来列表。我要评价第一?列表中的项目,如果不是读取错误,则 return 为真。

我认为这行得通,但行不通:

 val result = test() match {
      case r: DynamoReadError => Future.successful(false)
      case r: Registration    => Future.successful(true)
    }

我是 scala 的新手,所以在 return 类型和事物上苦苦挣扎。这是一个 Play api 调用,所以我需要在某个时候评估那个 boolen 未来。像这样:

 def health = Action {
    val isHealthy = h.testDynamo()
    val b: Boolean = Await.result(isHealthy, scala.concurrent.duration.Duration(5, "seconds"))
    Ok(Json.toJson(TestResponse(b.toString)))
  }

我认为这也可能是错误的,因为我不想使用 Await,但我也无法让异步工作。 对不起,我有点迷路了。

当我尝试评估结果时,我只收到一条关于未来的消息:

{
"status": 500,
"message": "Future(<not completed>) (of class scala.concurrent.impl.Promise$DefaultPromise)"
}

结果是 Future,因此如果不执行 Await.result 之类的操作(您稍后会做),就无法测试结果。您可以做的是将 Future 编辑的结果 return 修改为您需要的结果。

在你的情况下你可以这样做:

test().map(_.headOption.forall(_.isRight))

这将 return Future[Boolean] 然后您可以在 Await.result 调用中使用它。

工作原理如下:

  • mapFuture 的结果上调用一个函数,它是类型 List[Either[DynamoReadError, T]] 并且 return 是一个新的 Future给出该函数调用的结果。

  • _.headOption 占据列表的头部,return 是 Option[Either[DynamoReadError, T]]。如果列表中有一个或多个元素,则为 Some(...),如果列表为空,则为 None

  • forall 检查 Option 的内容和 return 对该选项的测试结果。如果 OptionNone 那么它 returns true.

  • _.isRight测试值Either[...]和returns true如果值为Right[...]false如果是 Left[...].

这会执行您指定的操作,但也许最好检查是否有任何结果失败,而不是只检查第一个结果?如果是这样,其实就简单了一点:

test().map(_.forall(_.isRight))

这会检查 List 中的所有条目是否为 Right,一旦找到 Left 就会失败。

Play 中 return 的问题是一个单独的问题,可能应该在一个单独的问题中。