代码之家  ›  专栏  ›  技术社区  ›  David

我的持久性类应该返回选项还是依赖异常?

  •  3
  • David  · 技术社区  · 14 年前

    我的应用程序的持久层由一个存储特性和一个实现类组成。我在这个问题上犹豫不决:是否应该 fetchFoo(key: Key) 方法应该返回 Option[Foo] 或者他们应该扔 FooNotFound 找不到密钥时出现异常?

    为了增加这个问题的味道,Java代码调用了持久层(它是用Scala编写的)。处理scala.选项在Java代码中?六羟甲基三聚氰胺六甲醚。

    事实上,直到昨天,持久层还是用Java编写的;我刚刚用Scala重新编写了它。作为一个Java代码库,它依赖于异常而不是返回空值;但是现在我遇到了scala.选项,我在重新考虑。在我看来,Scala不像Java那样热衷于异常。

    3 回复  |  直到 14 年前
        1
  •  4
  •   Kristian Domagala    14 年前

    我对一般问题的看法是,这取决于钥匙从哪里来。

    如果它们是由某个用户或不受信任的系统输入的,那么我使用 Option 因此,我可以有意义地表示未知密钥的可能性,并适当地处理它。

    另一方面,如果密钥来自一个已知的系统(这包括嵌入在最初来自系统的链接中的密钥),并且假定它们是有效的和存在的,我会将其作为运行时异常,由外部级别的catch all处理。对于链接示例,如果有人出于某种原因手动更改url中的键,则应将其视为未定义的行为,并应使用IMO中的异常。

    另一种思考方法是,当情况发生时,你将如何处理。如果你在使用 选择权 只不过是授权 None case对一些catch all错误的处理,那么异常可能更合适。如果要显式捕获NotFound异常并更改程序流(例如,要求用户重新输入密钥),请使用 选择权 ,或选中的异常(或 Either 在Scala中)以确保情况得到处理。

    关于与Java的集成, 选择权 一旦Scala运行库在类路径上可用,就很容易从那里使用。或者,有一个 选择权 实施于 Functional Java 图书馆。无论如何,我都不会使用 null 表示“未找到”。

        2
  •  2
  •   user382157 user382157    14 年前

    在Java中,可以调用Option的 isEmpty , isDefined get 没有任何特别的麻烦(真正有用的选项方法,例如 getOrElse ,是另一回事。)检查 已定义 if子句中的方法应比在try catch块中检查异常快。

        3
  •  0
  •   Landei    14 年前

    在某些情况下(比如你的例子),一个选项是好的,“一元”行为(map,flatMap,filter…)非常方便,但是在其他情况下,你需要更多关于问题原因的信息,可以更好地用一个例外来表达。现在您可能希望错误处理尽可能“统一”,所以我建议使用 或者 ,这将为您提供类似于Option的行为和类似于异常的表达式。

    在Java中,您只需要一个helper函数来“解包”一个或一个。如果它找到一个右(值),它将返回该值;如果它找到一个左(异常),它将重新抛出该值。在这之后,您将恢复正常的Java行为。