【发布时间】:2015-01-14 18:56:44
【问题描述】:
我有这段(元)代码处理我要更新的数据库对象T。
已知的只有此类对象的ID、检索对象的query 和执行的update。
def updateObject(...) : Either[(Int,String),(Int,T)] = {
T.update(
query,
update,
) match {
case 0 => Left(404, "No such object!")
case _ =>
T.findOne("id == objectId")
.map((200, _)) match {
case Some(result) => Right(result)
case _ => ???
}
}
}
T.update 对满足query 的对象执行更新并返回写入结果,该结果为整数(受更新影响的记录数)。
返回类型为Either[(Int,String),(Int,T)]:
- Left 是一个具有以下格式的元组:(error_code, error_message)。
- Right 的格式改为:(status_code, updated_object)。
如果受影响的记录数为 0,则该对象不存在,因此我返回 Left(404,"No such object")。
如果对象已更新,我需要获取它(因为我只有它的 id),将它映射到 (Int,T),然后在 Right 中返回它。
问题来了:
T.findOne 返回Option[T]。
我已经对对象执行了更新,因此它存在并且结果将始终为Some(T)。
我知道case _ => ??? 永远不会被调用,但是如果我不把它放进去,编译器会警告我匹配不是详尽的。
有没有更好的方法来处理这个问题(Option 总是保证是Some)?
(我试图避免使用Option.get 方法),而case _ => ??? 似乎是不必要且令人困惑的代码。
【问题讨论】:
-
似乎有一个极端的情况,即在您更新对象之后,在您再次检索它之前可以将其删除。为什么不针对这种情况使用您自己的另一个错误代码?
-
我正在这样做,但后来我意识到这是一个“超极端”的边缘情况。以前的代码是:
T.findOne("id == objectId").map((200, _)).toRight(500, "Object has been deleted") -
您不需要对选项进行匹配。你可以只做 T.findOne("id == objectId").get 如果结果不是 Some 会抛出异常
-
@Matteo Pcini “这不是一个好的模式” - 你能否提供一些参考,为什么它不是
-
@MatteoPacini “这不是一个好的模式”,因为它忽略了选项为
None的可能性,这正是您想要做的。一般来说,你可以说“这不是一种非常惯用的方式”来将你关于它的“元知识”“保证永远不会”应用于Option。关于。 “最重要的是它会引发异常”......这是“保证”在你的情况下永远不会发生,不是吗? :)
标签: scala functional-programming pattern-matching