更多FP方式而不是if / else

时间:2015-09-03 10:24:08

标签: scala

想要获得更多的FP方式开发。在我的情况下,DAO可以返回Object或None。 但我应该保证所有对象是否存在

像这样实施

def get(...): String = {
    val user1 = UserDAO.getUser(...)
    val user1 = UserDAO.getUser(...)
    val userN = UserDAO.getUser(...)

if (user1.isEmpty || ser2.isEmpty || ... ) {
 return "error"
} else {
 ... 
}

它可以实现更多功能的方式。没有混乱if / else?

BR!

4 个答案:

答案 0 :(得分:3)

列出您传递给getUser的参数,并使用mapforall

val userIds = List(...)
val dbUsers = userIds.map(UserDAO.getUser)

如果你不想使用if / else,你可以这样做,虽然感觉有点颠倒,可能完全模糊了你的意图:

dbUsers.collectFirst { case user if user.isEmpty => "error" } getOrElse { "ok" }

然而,afaik if / else在fp(或者至少在scala开发人员中)并不是那么令人讨厌,所以你也可以用更具表现力和简洁的方式来编写它:

if (dbUsers.forall(_.nonEmpty)) "ok" else "error"

或者,在逆逻辑中:

if (dbUsers.exists(_.isEmpty)) "error" else "ok"

答案 1 :(得分:2)

考虑

if (Seq(user1,user2,userN).exists(_.isEmpty)) "error"
else ""

existsisEmpty,我们检查是否未定义任何用户。当遇到包含谓词的第一个项时,此方法会暂停Seq上的迭代。

答案 2 :(得分:0)

您可以使用for-comprehension对所有3 Option[User]进行flatmap,并指定如果所有3个用户都存在会发生什么。

然后使用getOrElse指定如果这些用户中的任何一个是None

会发生什么
def get(...): String = {
    val namesOpt = for {
        u1 <- UserDAO.getUser(...)
        u2 <- UserDAO.getUser(...)
        u3 <- UserDAO.getUser(...)
    } yield u1.name + u2.name + u3.name

    namesOpt getOrElse "error"
}

答案 3 :(得分:0)

val users = /* collection of Option[User] types */
users.find(!_.isDefined).fold("ok") { _ => "error" }

或..

users.find(_.isEmpty).fold("ok") { _ => "error" }