Scala - 使用模式匹配案例的清洁方式

时间:2017-04-18 16:24:42

标签: scala

我正在使用很多Option,我需要使用模式匹配/案例几乎每次调用都要检查对象是否为None。

当您使用大量匹配案例时,是否可以编写更清晰的代码?

def process(schema: Option[String], body: String, token:String, queueInfo: Map[String, String]) = {
  jsonSchemaService.findByDescriptionFromCache(schema) match {
    case Some(jsonSchema) =>
      jsonSchema.schema match {
        case Some(s) =>
          val ku = buildKinesisUtils(token, queueInfo)
          validateAndPublish(body, s, ku)
        case None =>
          Future(Left(SchemaNotDefinedException(s"O Json schema [$schema] não possui um schema definido")))
      }
    case None =>
      Future(Left(SchemaNotFoundException("Não foi possível encontrar o JsonSchema informado")))
  }
}

3 个答案:

答案 0 :(得分:3)

使用.map.flatMap来避免选项上的模式匹配:

jsonSchemaService
    .findByDescriptionFromCache(schema)
    .map { jsonSchema =>
      jsonSchema.schema.map { s =>
        val ku = buildKinesisUtils(token, queueInfo)
        validateAndPublish(body, s, ku)
      }.getOrElse(Future(Left(SchemaNotDefinedException(s"O Json schema [$schema] não possui um schema definido"))))
    }.getOrElse(Future(Left(SchemaNotFoundException("Não foi possível encontrar o JsonSchema informado"))))
  

注意:在不知道所有使用的方法的签名的情况下生成正确的答案有点难......但它应该以某种方式接近你想要的

答案 1 :(得分:2)

使用模式匹配并不是处理选项的惯用方法。最好使用map和flatmap等方法,并利用for comprehension来处理选项。如果您每次检查选项是否为无,那么它都不比空检查好。

由于您的方法正在返回选项但您实际上想要Eithers,您可以使用toRight方法将这些选项转换为Eithers。

def process(schema: Option[String], body: String, token:String, queueInfo: Map[String, String]) = {
     val res = for {
        jsonSchema <- jsonSchemaService.findByDescriptionFromCache(schema).toRight(SchemaNotFoundException("Não foi possível encontrar o JsonSchema informado")).right
        s <- jsonSchema.schema.toRight(SchemaNotDefinedException(s"O Json schema [$schema] não possui um schema definido")).right
      } yield s
    res.fold(e => Future(Left(e)), s => validateAndPublish(body, s, buildKinesisUtils(token, queueInfo)))
}

自scala 2.12开始,默认情况下,这两种情况都是右偏,因此不再需要.right次调用。

答案 2 :(得分:0)

您正在做的事情实际上是GridView

fold