全部。我正在读一本书,其中一个想法是在写一个方法时“不要返回null”。当函数必须返回null时,他建议“抛出异常”或“使用特殊情况”。
如果方法返回类型是一个列表,我知道我可以返回一个空列表而不是null。但是,如果返回类型是特定对象,该怎么办?例如,一种按唯一ID搜索数据库并返回结果的方法。如果方法找不到任何东西,我应该返回什么?
我试图使用“抛出异常”但最终为任何调用该函数的地方编写更多编码和附加逻辑。
任何建议将不胜感激。
答案 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 */
}