返回值与返回错误代码?

发布于 2024-12-08 21:18:34 字数 1614 浏览 4 评论 0原文

这是一个一般性的编程问题,与任何特定语言无关。

新程序员通常会编写一个方法来计算某个值,然后返回该值:

public Integer doSomething()
{
   // Calculate something
   return something;
}

public void main()
{
  Integer myValue = doSomething();
}

但是当的计算过程中发生异常时>某事,处理异常的最佳方法是什么,特别是在向用户提供反馈时?如果您对 something 的计算进行了 try/catch,并且捕获了异常,那么您会返回什么?没有计算任何内容,所以返回 null 吗?一旦返回它(无论它是什么),您是否需要在父方法中执行另一个 try/catch 来检查是否返回了有效值?如果没有,那么确保向用户提供一些反馈?

我听到表两边关于根本不返回值的争论,而是将计算值设置为指针或全局变量,并只从方法返回错误代码,然后(在父方法中)简单地相应地处理错误代码。

有没有最佳实践或方法?是否有任何好的资源可以让人们了解更多有关处理此问题的最佳方法?

更新澄清

考虑以下代码:

public void main()
{
  int myValue = getMyValue();

  MyUIObject whatever = new MyUIObject();
  whatever.displayValue(myValue); // Display the value in the UI or something
}

public Integer getMyValue()
{
  try
  {
    // Calculate some value
  } catch (exception e) {
    // ??
  }
  return value;
}

我调用该方法来获取一些 int 值,然后返回它。回到 main(),我对该值执行一些操作,例如在本例中将其显示在日志中。通常我会在用户界面中显示该值。

无论如何,如果在 getMyValue() 中捕获异常,那么 value 是否会返回但它为空?那么 main() 中会发生什么?我是否还必须测试它是否是 main() 中的有效值?

我需要程序相应地处理错误并继续。下面有人建议通过 getMyValue() 方法在 UI 中显示适当的信息。我看到两个潜在的问题:

  1. 似乎我会将业务逻辑与(在本例中)UI 逻辑混合在一起。
  2. 我必须将 MyUIObject 的引用传递给 getMyValue() 或其他内容,以便我可以从函数内访问它。在上面的简单示例中,这没什么大不了的,但如果有一堆 UI 元素需要根据 getMyValue() 中发生的情况进行更新或更改,则将它们全部传递可能会是一个麻烦的事情。有点多......

我已经阅读了很多有关所有这些基础知识的内容,但我似乎无法找到上述情况的直接答案。我感谢任何帮助或见解。

This is a general programming question, not pertaining to any specific language.

A new programmer typically will write a method that calculates some value, then returns the value:

public Integer doSomething()
{
   // Calculate something
   return something;
}

public void main()
{
  Integer myValue = doSomething();
}

But when an exception occurs during the calculation of something, what is the best way to handle the exception, especially when giving the user feedback? If you do a try/catch of the calculation of something and if an exception is caught, what do you return? Nothing was calculated, so do you return null? And once you return it (whatever it may be), do you need to do another try/catch in the parent method that checks to see if a valid value was returned? And if not, then make sure the user is given some feedback?

I have heard arguments on both sides of the table about never returning values at all, but instead setting calculated values as pointers or global variables and instead returning only error codes from methods, and then (in the parent method) simply handling the error codes accordingly.

Is there a best practice or approach to this? Are there any good resources that one could access to learn more about the best way to handle this?

UPDATE for Clarification

Consider the following code:

public void main()
{
  int myValue = getMyValue();

  MyUIObject whatever = new MyUIObject();
  whatever.displayValue(myValue); // Display the value in the UI or something
}

public Integer getMyValue()
{
  try
  {
    // Calculate some value
  } catch (exception e) {
    // ??
  }
  return value;
}

I call the method to get some int value, then I return it. Back in main(), I do something with the value, like show it in the Log in this case. Usually I would display the value in the UI for the user.

Anyways, if an exception is caught in getMyValue(), so does value get returned but it's null? What happens in main() then? Do I have to test if it's a valid value in main() as well?

I need the program to handle the error accordingly and continue. Someone below suggested displaying the appropriate information in the UI from within the getMyValue() method. I see two potential issues:

  1. It seems like I would be mixing the business logic with (in this case) the logic for the UI.
  2. I would have to pass a reference of the MyUIObject to the getMyValue() or something so I could access it from within the function. In the above simple example that is no big deal, but if there is a BUNCH of UI elements that need to be updated or changed based off of what happens in getMyValue(), passing them all might be a bit much...

I've read a bunch about the fundamentals of all of this but I can't seem to find a straight answer for the above situation. I appreciate any help or insight.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

虐人心 2024-12-15 21:18:34

我认为你不太了解异常。

如果抛出异常,则不会从函数正常返回:

public Integer doSomething()
{
   throw new my_exception();
   // The following code does NOT get run
   return something;
}

public void main()
{
  Integer myValue = doSomething();
}

异常的主要优点是:

  • 您可以像一切都成功一样编写代码,这通常更清晰
  • 异常很难忽略。如果未处理异常,通常会给出明显且响亮的错误,并带有堆栈跟踪。这与错误代码形成对比,在错误代码中,忽略错误处理比不忽略错误处理更容易

我推荐 Eric Lippert 的这篇文章,其中讨论了异常以及何时适合或不适合处理异常。


更新(回应评论):

你绝对可以处理异常并继续,你可以通过捕获异常来做到这一点。

例如:

try
{
   // Perform calculation
}
catch (ExceptionType ex)
{
   // A problem of type 'ExceptionType' occurred - you can do whatever you
   // want here.
   // You could log it to a list, which will be later shown to the user,
   // you could set a flag to pop up a dialog box later, etc
}

// The code here will still get run even if ExceptionType was thrown inside
// the try {} block, because we caught and handled that exception.

这样做的好处是,您知道出了什么问题(从异常类型),以及详细信息(通过查看 ex 中的信息),因此您
希望您能获得做正确事情所需的信息。


更新 2 响应您的编辑:

您应该在能够以您想要的方式响应的层处理异常。对于您的示例,您是正确的,您不应该在代码的深处捕获异常,因为您无权访问用户界面等,因此您实际上无法做任何有用的事情。

您的示例代码的这个版本怎么样:

public void main()
{
  int myValue = -1; // some default value
  String error = null; // or however you do it in Java (:
  
  try
  {
    getMyValue();
  }
  catch (exception e)
  {
    error = "Error calculating value. Check your input or something.";
  }

  if (error != null)
  {
    // Display the error message to the user, or maybe add it to a list of many
    // errors to be displayed later, etc.
    // Note: if we are just adding to a list, we could do that in the catch().
  }

  // Run this code regardless of error - will display default value
  // if there was error.
  // Alternatively, we could wrap this in an 'else' if we don't want to
  // display anything in the case of an error.
  MyUIObject whatever = new MyUIObject();
  whatever.displayValue(myValue); // Display the value in the UI or something
}

public Integer getMyValue()
{
  // Calculate some value, don't worry about exceptions since we can't
  // do anything useful at this level.
  return value;
}

I think you do not quite understand exceptions.

If you throw an exception, you do not return from the function normally:

public Integer doSomething()
{
   throw new my_exception();
   // The following code does NOT get run
   return something;
}

public void main()
{
  Integer myValue = doSomething();
}

The main advantages of exceptions are:

  • You can write your code as though everything is succeeding, which is usually clearer
  • Exceptions are hard to ignore. If an exception is unhandled, typically an obvious and loud error will be given, with a stack trace. This contrasts with error codes, where it is much easier to ignore the error handling than not.

I recommend this post by Eric Lippert, which discusses exceptions and when it is and is not appropriate to handle them.


UPDATE (in response to comment):

You can absolutely handle an exception and continue, you do this by catching the exception.

eg:

try
{
   // Perform calculation
}
catch (ExceptionType ex)
{
   // A problem of type 'ExceptionType' occurred - you can do whatever you
   // want here.
   // You could log it to a list, which will be later shown to the user,
   // you could set a flag to pop up a dialog box later, etc
}

// The code here will still get run even if ExceptionType was thrown inside
// the try {} block, because we caught and handled that exception.

The nice thing about this is that you know what kind of thing went wrong (from the exception type), as well as details (by looking into the information in ex), so you
hopefully have the information you need to do the right thing.


UPDATE 2 in response to your edit:

You should handle the exception at the layer where you are able to respond in the way you want. For your example, you are correct, you should not be catching the exception so deep down in the code, since you don't have access to the UI, etc and you thus can't really do anything useful.

How about this version of your example code:

public void main()
{
  int myValue = -1; // some default value
  String error = null; // or however you do it in Java (:
  
  try
  {
    getMyValue();
  }
  catch (exception e)
  {
    error = "Error calculating value. Check your input or something.";
  }

  if (error != null)
  {
    // Display the error message to the user, or maybe add it to a list of many
    // errors to be displayed later, etc.
    // Note: if we are just adding to a list, we could do that in the catch().
  }

  // Run this code regardless of error - will display default value
  // if there was error.
  // Alternatively, we could wrap this in an 'else' if we don't want to
  // display anything in the case of an error.
  MyUIObject whatever = new MyUIObject();
  whatever.displayValue(myValue); // Display the value in the UI or something
}

public Integer getMyValue()
{
  // Calculate some value, don't worry about exceptions since we can't
  // do anything useful at this level.
  return value;
}
メ斷腸人バ 2024-12-15 21:18:34

异常是面向对象语言(OOL)的一个属性。如果您使用 OOL,您应该更喜欢异常。这比返回错误代码要好得多。您可以找到一些很好的示例,说明错误代码方法如何生成比基于异常的代码长得多的源代码。例如,如果您想读取文件并对其执行某些操作并以不同的格式保存。您可以毫无例外地在 C 中执行此操作,但您的代码将充满 if(error)... 语句,也许您会尝试使用一些 goto 语句,也许一些宏来使其更短。但也绝对不透明且难以理解。此外,您经常会忘记测试返回值,这样您就不会看到错误并且程序会继续运行。那不好。另一方面,如果您使用 OOL 编写并使用异常,则您的源代码重点关注“没有错误时做什么”,而错误处理则位于不同的位置。对于许多可能的文件错误,只需一个错误处理代码。源代码更短,更清晰等。

我个人永远不会尝试以面向对象语言返回错误代码。 C++ 是一个例外,其中的例外系统有一些限制。

Exceptions is a property of object oriented languages (OOL). If you use OOL, you should prefer exceptions. It is much better than to return error codes. You can find nice examples how the error-codes approach generates a vastly longer source code than exceptions based code. For example if you want to read a file and do something with it and save in a different format. You can do it in C without exceptions, but your code will be full of if(error)... statements, maybe you will try to use some goto statements, maybe some macros to make it shorter. But also absolutely nontransparent and hard to understand. Also you can often simply forget to test the return value so you don't see the error and program goes on. That's not good. On the other hand if you write in OOL and use exceptions, your source code focuses on "what to do when there is no error", and error handling is in a different place. Just one single error handling code for many possible file errors. The source code is shorter, more clear etc.

I personally would never try to return error codes in object oriented languages. One exception is C++ where the system of exceptions have some limitations.

柒七 2024-12-15 21:18:34

你写道:

我听到表两边关于根本不返回值的争论,而是将计算值设置为指针或全局变量,并只从方法返回错误代码,然后(在父方法中)简单地处理相应的错误代码。

[编辑]
实际上,异常可以看作是错误代码,它伴随着相关的消息,作为程序员,你应该知道你的异常必须在哪里被捕获、处理并最终显示给用户。只要您让异常传播(在被调用函数的堆栈中向下传播),就不会使用返回值,因此您不必关心处理相关的丢失值。良好的异常处理是一个相当棘手的问题。

正如 jwd 回答的那样,我不认为有必要在方法中引发异常,然后在同一方法中处理异常只是为了返回错误值。澄清:

 public Integer doSomething(){

     try{

         throw new my_exception();}

     catch{ return err_value;} 

     }

毫无意义。

You wrote:

I have heard arguments on both sides of the table about never returning values at all, but instead setting calculated values as pointers or global variables and instead returning only error codes from methods, and then (in the parent method) simply handling the error codes accordingly.

[EDIT]
Actually, excetion can be seen as error code, which comes along with the relative message, and you as the programmer should know where your exception must be caught, handled and eventually display to the user. As long as you let the exception to propagate (going down in the stack of called functions) no return values are used, so you don't have to care about handling related missed values. Good exception handling is a quite tough issue.

As jwd replied, I don't see the point to raise an exception in a method and then handle the excpetion in the same method just to return an error value. To clarify:

 public Integer doSomething(){

     try{

         throw new my_exception();}

     catch{ return err_value;} 

     }

is pointless.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文