2017-04-18 67 views
0

我正在使用很多Option,並且我需要使用模式匹配/案例幾乎每次調用來檢查對象是否爲None。Scala - 使用模式匹配案例的更清潔方式

當您使用大量匹配案例時,可以編寫更清晰的代碼嗎?

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

回答

2

使用模式匹配不是真正的處理選項的慣用方式。最好使用map和flatmap之類的方法,並利用理解來處理選項。如果你每次檢查是否有一個選項是None,它不會比空檢查好得多。

由於您的方法正在返回選項,但您實際上需要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))) 
} 

由於斯卡拉2.12,所以.right通話也不再需要要麼是右側偏置默認。

+1

@placplacboom然後最終結果是'Future(Left(SchemaNotFoundException))'。操作快速。一旦你得到一個'Left',則返回Left並且其他操作都不會運行。最後一行我們轉換了,左側被包裝在Future(Left)中,以便它具有正確的類型,如果它是Right(成功的情況下),我們將結果傳遞給你的函數。這樣,你的代碼只需要在每一步處理成功案例。 – puhlen

+0

我的不好,我刪除了其他評論。我問的是對象'[Throwable,String]'。有可能''.right'上? – placplacboom

+0

Nvm! '.fold'完成這項工作:)謝謝 – placplacboom

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

注:這是一個有點難以產生一個正確的答案不知道所使用的所有方法的簽名......但它應該在某種程度上接近你想要的東西

+0

基本上,我想返回一個未來[可[Throwable,String]],但我寫了很多匹配/案例。看起來像一個Java代碼。 – placplacboom

+1

像Option.map,Option.flatMap,Future.map/flatMap和Future.recover/Future.recoverWith這樣的方法可能對這種類型的案例有用 – pedrorijo91

+0

好!什麼是使用[Left,Right]的最佳方法? – placplacboom

0

你正在做的事實際上是一個fold

option.fold(noneCase)(s => someCase(s))