不返回null - 搜索功能返回什么

时间:2012-04-05 21:41:50

标签: coding-style

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

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

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

任何建议将不胜感激。

5 个答案:

答案 0 :(得分:3)

如果您不想返回null,那么您可以使用类似Optional类的内容。

答案 1 :(得分:1)

Null被定义为不存在,似乎与你想要的完全吻合。如果您的代码没有返回任何内容,对吧?

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

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

如果不存在是完全有效的返回值,那么为什么要返回异常?假设你已经有了代码来处理从查询中返回的不存在的值,那么根本不需要抛出异常。

答案 2 :(得分:1)

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

这个实例的一个例子是C#中的几个LINQ functions。这些方法可以返回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中有数据访问层,并且需要将数据库故障传递回父程序,有时最好的方法是通过异常处理。

答案 3 :(得分: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

答案 4 :(得分:0)

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

代码应该看起来大致相同:

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


/* almost the same as this */

SearchResult someResult = searchForStuff();

if ( someResult == null ) {
    /* do stuff */
}