如何清理这段丑陋的 Scala 代码
How do I clean this ugly piece of Scala code
这是一个非常简单的用例,但我找不到任何处理它的优雅方法。
低于我正在尝试做的事情。非常明确...
注: users.byEmail
return一个Future[Option[User]]
.
override def invokeBlock[A](request: Request[A], block: UserRequest[A] => Future[Result]): Future[Result] = {
val useEmail: Option[String] = request.session.get("userEmail")
if (useEmail.isEmpty) {
return Future.successful(Results.Unauthorized(("No email")))
}
val user: Option[User] = Await.result(users.byEmail(useEmail.get), Duration(1, TimeUnit.MINUTES))
if (user.isEmpty) {
return Future.successful(Results.Unauthorized(("No user")))
}
block(UserRequest(user.get, request))
}
"correct" 的写法是什么?
这是一个更简洁的版本:
def invokeBlock[A](request: Request[A], block: UserRequest[A] => Future[Result]): Future[Result] =
request.session.get("userEmail") match {
case None =>
Future.successful(Results.Unauthorized(("No email")))
case Some(useEmail) =>
users.byEmail(useEmail).flatMap {
case None =>
Future.successful(Results.Unauthorized("No user"))
case Some(user) =>
block(UserRequest(user, request))
}
}
主要变化是
在 Option
class
上使用 match
而不是 if
不要使用 return
,这很少有必要,而且可能不会如您所愿
在 Future
上使用 flatMap
而不是 Await.result
以避免阻塞
这是一个非常简单的用例,但我找不到任何处理它的优雅方法。
低于我正在尝试做的事情。非常明确...
注: users.byEmail
return一个Future[Option[User]]
.
override def invokeBlock[A](request: Request[A], block: UserRequest[A] => Future[Result]): Future[Result] = {
val useEmail: Option[String] = request.session.get("userEmail")
if (useEmail.isEmpty) {
return Future.successful(Results.Unauthorized(("No email")))
}
val user: Option[User] = Await.result(users.byEmail(useEmail.get), Duration(1, TimeUnit.MINUTES))
if (user.isEmpty) {
return Future.successful(Results.Unauthorized(("No user")))
}
block(UserRequest(user.get, request))
}
"correct" 的写法是什么?
这是一个更简洁的版本:
def invokeBlock[A](request: Request[A], block: UserRequest[A] => Future[Result]): Future[Result] =
request.session.get("userEmail") match {
case None =>
Future.successful(Results.Unauthorized(("No email")))
case Some(useEmail) =>
users.byEmail(useEmail).flatMap {
case None =>
Future.successful(Results.Unauthorized("No user"))
case Some(user) =>
block(UserRequest(user, request))
}
}
主要变化是
在 Option
class
match
而不是 if
不要使用 return
,这很少有必要,而且可能不会如您所愿
在 Future
上使用 flatMap
而不是 Await.result
以避免阻塞