2016-07-06 83 views
2

我做這樣的事情:過濾裏面換理解與期貨

(for { 
    data <- Future(getData) 
    updated = makeChanges(data) if updated != data 
    _ <- Future(saveUpdates(updated)) 
    _ <- Future(recordTransaction) 
} yield()).recover { case e: NoSuchElementException =>() } 

當過濾器並不滿意,它跳過剩下的兩個步驟,通過拋出一個異常(不好),那(好!)我必須抓住並處理結束。流量控制使用異常不會覺得太高雅了我,雖然,我從明顯的不知道是否有更好的方式來做到這一點,除了 - 與if語句包裹的全部剩餘線路:

_ <- if(updated != data) Future(saveUpdates(updated)) else Future.successful(()) 
    _ <- if(updated != data) ... 
+0

如果你可以改變makeChanges返回的元組(改爲:更新布爾:數據)就可以了,你能模式匹配,並決定哪些行動在這種情況下。它會使它更清潔 –

+0

@LouisF。不明白你的意思。我可以很容易地在'updated!= data'上模式匹配,但不知道如何使用它來使其更清潔。用'match ... case'剪掉上一個剪下的'if ... else ..'? – Dima

回答

2

我不假設你可以避免使用理解的流量控制的異常,那麼你可以使用嵌套表達式而不是過濾器,並手動處理條件給scala它所需的返回類型,以防條件不滿足:

for { 
    data <- Future(data) 
    updated = makeChanges(data) 
    res = { 
    if (updated != data) Future.successful(()) 
    else for { 
     _ <- Future(saveUpdates(updated)) 
     _ <- Future(recordTransaction) 
    } yield() 
    } 
} yield res 

但是,對於這個例子,我會去簡單的方法,並放棄理解,導致更多可讀的代碼(可能是你的真實使用情況是比較複雜的,雖然):

Future(data).flatMap(d => { 
    val updated = makeChanges(d) 
    if(updated == d) Future.successful(()) 
    else Future(saveUpdates(updated)).map(_ => recordTransaction) 
}) 
+0

是的,我自己並不是一個理解力強的粉絲,但在這種特殊情況下,我認爲你的建議根本不是「更具可讀性」:(如果有什麼我不喜歡過度使用理解,這是過度的嵌套。 – Dima