2015-06-05 27 views
1

模式:A future被深埋在條件鏈(if,map等)的深處。對於任何情況下,這個深度鏈不滿意,有一個單一的「其他」future未來深埋在一系列具有共同「未來」未來條件的未來

爲了說明這一點,我把兩個例子放在一起。

f具有條件語句中分離出來,並因此需要將「其他」 futuree在代碼)指定多次:

def f(uo: Option[User]): Future[String] = { 
    val e = Future.successful("b") 
    // note how `e` is specified twice below 
    uo.map(u => if (u.id != 123) Future.successful("a") else e).getOrElse(e) 
} 

g具有條件語句一起,因此「其他」 future指定只有一次:

def g(uo: Option[User]): Future[String] = { 
    val e = Future.successful("b") 
    if (uo.isDefined && uo.get.id != 123) { 
    Future.successful("a") 
    } else e // note how the `e` is specified only once 
} 

我覺得後者更好,更可讀,雖然我不喜歡它100%,因爲uo.isDefined && uo.get...是有一點,好吧,你知道,不是很好。 :)首先的uo.map(u => ...更清晰,但我不是100%滿意,因爲e被多次指定。

隨着更深入,更復雜的代碼,有點煩人不得不做大量的拆包,以結合條件或必須在任何地方重複相同的「其他」。

問題:除了上面給出的兩個方法之外,還有其他方法嗎?

回答

1

可以經常使用模式匹配來摺疊嵌套:

def f(uo: Option[User]): Future[String] = uo match { 
    case Some(u) if u.id != 123 => Future.successful("a") 
    case _ => Future.successful("e") //Will match for both None and Some(123), as desired 
} 

您可能也有興趣的collect方法,它接受部分功能將被用作圖和未定義的輸入返回None

def f(uo: Option[User]): Future[String] = uo.collect { 
    case u if u.id != 123 => Future.successful("a") 
}.getOrElse(Future.successful("e"))