2

全部。我正在读一本书,其中一个想法是在编写方法时“不要返回 null”。当函数必须返回 null 时,他建议“抛出异常”或“使用特殊情况”。

如果方法返回类型是一个列表,我知道我可以返回一个空列表而不是 null。但是,如果返回类型是特定对象怎么办。例如,通过唯一 id 搜索数据库并返回结果的方法。如果方法找不到任何东西,我应该返回什么?

我尝试使用“抛出异常”,但最终为调用该函数的任何地方编写了更多编码和附加逻辑。

任何建议将不胜感激。

4

5 回答 5

3

如果您不想返回 null,则可以使用Optional类之类的东西。

于 2012-04-05T21:55:01.977 回答
1

Null 被定义为不存在,这似乎与您想要的完全吻合。如果你的代码什么也不返回,对吧?

但是,一如既往,这取决于。

如果您的代码不打算返回任何内容,那么这样做可能会导致无法解决的问题。在这种情况下,抛出异常肯定更好。1 / null,不会在任何地方工作。

如果不存在是一个完全有效的返回值,那么为什么要返回异常?当然,假设您已经准备好代码来处理从查询返回的不存在的值,那么根本不需要抛出异常。

于 2012-04-05T21:55:43.037 回答
1

抛出异常是一项代价高昂的操作,因为存在上下文切换并且必须收集大量调试信息,因此您希望避免将它们作为控制流程流的一种方式(尤其是如果您可以在不抛出异常的情况下处理这种情况)。为了避免捕获异常,完全可以接受返回 null。

这方面的一个例子是 C# 中的几个LINQ 函数。这些方法可以返回 null:

SingleOrDefault(); // returns a single instance of an object, or null if not found

FirstOrDefault(); // returns the first matching object, or null if not found

这允许您检查 null 而无需尝试使用异常处理来找出控制流。

我能想到的一个异常(请原谅双关语)是使用异常跨程序边界进行通信。例如,如果您有一个单独的 DLL 中的数据访问层,并且您需要将数据库故障传达回父程序,有时最好的方法是通过异常处理。

于 2012-04-05T22:26:26.393 回答
1

如果可能是您可以返回的可能值,那么如果您找不到任何东西Null,则不应返回。Null例如,在:

[1, 2, 3, Null, 5].find(nonInteger) -> Null
[1, 2, 3, 4].find(nonInteger) -> Null

.find函数不能返回Null表示失败,因为有时它会返回Null成功!相反,您可以更改语义,或使用特殊对象:

# changed semantics (with extra information returned)
[1, 2, 3, Null, 5].find(nonInteger) -> index=4, value=Null
[1, 2, 3, 4].find(nonInteger) -> index=Null, value=Null

# changed semantics (with wrapper)
[1, 2, 3, Null, 5].find(nonInteger) -> new Maybe(Null)
[1, 2, 3, 4].find(nonInteger) -> new Maybe()

# special object
NoResultFound = new object()
[1, 2, 3, Null, 5].find(nonInteger) -> Null
[1, 2, 3, 4].find(nonInteger) -> NoResultFound
于 2012-04-05T22:41:33.490 回答
0

我认为返回 null 没有任何问题,但抛出异常似乎是最明智的选择。您最好的选择是创建您自己的自定义异常类。

无论哪种方式,代码看起来都应该差不多:

try {
    SearchResult someResult = searchForStuff();
}
catch ( ResultNotFoundException rnfe ) {
    /* do stuff */
}


/* almost the same as this */

SearchResult someResult = searchForStuff();

if ( someResult == null ) {
    /* do stuff */
}
于 2012-04-05T21:56:03.727 回答