For example, the Add method of a user Class, returns the user object instance in case of success, returns false in case of failure and can get the reason string of failure by the GetError method ....
Speaking of which, I seem to understand that the Add method should always return the user object, or throw an exception?
But in that case, there's no difference in the amount of code they have. The problem is that even if there is no catch exception at the call to the Add method, the exception can be thrown further up until it is processed or the process crashes? But in the final analysis, what is the difference between this and the natural collapse of the program?
----above for talking to yourself, here are the questions----
What is the difference between throwing an exception and returning false, and what is the use of both in what scenario?
Reply content:
First of all, this is a good question. A deeper understanding of the difference is one of the hallmarks of a middle-level programmer.
First clarify a misunderstanding, it is very slow. The implementation of the exception needs to save the necessary information of the exception throw point to the exception capture point, which is the main basis for people's criticism of abnormal performance. But this is wrong. First, the performance of the behavior equivalent to the exception in the style of the return error is most often compared to the performance of language built-in exceptions. This gap is particularly noticeable for OS that support native exceptions, such as Windows, and second, for non-stack-based invocation implementations, there are few differences in the performance of exception and return errors, just different styles.
Back to the question, what is the essential difference between an exception and a return error? A: Exceptions are strongly typed, type-safe branch processing techniques, and the return error is its weakened, insecure version.
Look at the characteristics of the return error first. In general, you need to identify errors with special return values, which means that you need to overload specific worthwhile meanings. Suppose an operation returns an int value because it is not possible to return a negative number (such as an absolute value), we can generally use-one as an indication of an operation failure (such as a function library call loading error). 1 There is no special meaning in the int type, but we enforce the semantics here, and this semantics is weak. There is no way to ensure correctness through type system checks.
An enhanced approach is to return both values at the same time. Some languages have built-in support, and no built-in support can be modeled by defining a structure that contains the correct return type and the type of error, respectively. The advantage is that the channel that transmits the information is separated.
There is a significant drawback to returning an error anyway: The caller must explicitly check for the error value. When an error occurs, the current operation must be terminated, and when an error is returned, it is generally necessary to define a completely new type of error. This causes the operation to not be arbitrarily simple to combine, such as module B calls module A to return the error defined by B, while module C calls a error, you need to return the C definition of the error, and these two types of errors are often incompatible. The combination of related code must include a large number of sticky code, which results in code bloat, and is very error-prone. For systems with clearly defined interfaces, a common set of error codes is generally defined to simplify their complexity. The OS kernel is an example that provides an error code table that fits all OS calls. However, the error code used internally is much more, and the internal error code is often mapped to an external error code on the interface.
Exceptions are a secure branch-processing technique. Because it is closely related to error handling, it is easy to treat anomalies directly as error handling, and even the name "anomaly" carries with it a thick false meaning. But this is a misunderstanding. The theoretical basis of the anomaly is that it is assumed that in some branch processing, a branch and other branches occur very infrequently. Instead of dealing equally with common and extremely rare situations (think about the fact that normal processing code and error-handling code are often the same, in most cases the latter is more) than just dealing with normal situations and attributing uncommon situations to a single unified process. So when we write code, we just focus on the normal situation. In the event of an error, a special process will help the programmer go directly to the place where the error handling is defined.
That's a little simplistic. In general, you cannot jump back directly. Because between exception-throwing points and exception-handling points, there may be values that are in a non-uniform state, resources waiting to be freed, and so on. So in general, special processes need to retrace the call stack to ensure the execution of the transaction. But only this particular process is not enough, it must have the appropriate matching code. This leads to additional complexity. The RAII concept introduced by C + + is a pioneering work, but it still does not completely eliminate the programmer.
Because the exception is a specific type, the signature of a function is not just the input parameter list, the output parameter plus the function name, but also the list of possible exceptions to be thrown. Because each module defines a different hierarchy of exceptions, this results in additional combinations of difficulties. However, the combination of the return error value is difficult, which results in a compile-time type error, while the latter is a run-time error. In general, the sooner the error is exposed, the better we tend to the former.
Ideally, an exceptionally well-structured system would not have run-time errors (presumably, not expanded). However, because of the above mentioned reasons, in the case of the existing exception support, the code is also complex, redundant, difficult to maintain.
Above is the basic difference between exceptions and errors.
Second part of the trailer: Is there an elegant way to solve the above problems?
My point is that there is. But because the existing capacity is not yet without any reference to direct clarification of this issue, I will leave it to the careful consideration, bathing incense, for non-mobile input in the case given, please look forward to. are error-handling strategies, oo language is more prone to anomalies, compared to determine the possible error condition of a function, "throw" the state of the complete exception object is considered to be better encapsulation; In the case where you say false is the simplest case, in which case the exception may not have an advantage It is generally thought that using exceptions simplifies complex error-handling code, and that try catch is more readable than if else code if the program does not need to terminate execution (the error-handling strategy is obvious and the state can be richer, although this is not absolute).
result = func();if (result === ERR_NO_1) { ... } else if (result === ERR_NO_2) { } else { ...}
A very simple example, you have to parse the JSON request back into the package, only the code that returns false may be
if(jsonObj.has("xxx")){ if(jsonObj.has("xxxxx")) { //......... returntrue; }}returnfalse;
Wrote some, but felt there was nothing to say. Many questions of doubt, see more write much more naturally know. Many times there is no good or bad, only the unity of style. such as C + + support exception language, in many code base is completely exception free, and in the form of Class C to handle exceptions.
There are two types of exceptions, one of which is "I know this place can go wrong, the caller must know the risk of the error", and the other is "this is a mistake, there is no room to save the crash." These two types of exceptions in Java are the difference between checked exception and unchecked exception.
Exceptions are not limited to error handling, but are often used to separate the normal scenario and edge cases. For example, read a file and count the number of occurrences of each word in the file. Here in Python syntax:
word_count=dict()forwordinwords: try: word_count[word]+=1 exceptKeyError: word_count[word]=1
A function that throws an exception does not need to return a bool.
A function that is designed to return a bool or a pointer does not require an exception.
That is, the exception and the return value are never at the same time (this is, of course, my own understanding).
(I think that if the add function in your question fails, then you don't throw an exception, and if you don't normally fail, you can throw an exception.) However, you do not have to add a try to each of the add functions. It doesn't add up to see if your program logic can and should be restored. (You can also write an auxiliary function to call try add inside it: Other places use this helper function:), continue to run. Otherwise, add a try at the program entry and exit.)
It seems that you have not answered the good question, tomorrow on the computer to discuss the discussion. can return to either or maybe is convenient, such as either such as the error message is rich enough to not need an exception from the Windows implementation of a branch statement, one is SEH or global callback processing, the latter can be very good to prevent the situation when the program is not expected to collapse! First, exceptions are predictable, so it's predictable. Second, the exception does not care about the conditions that occur and cares how to clean up. Thirdly, exceptions are defined errors, which are easier to locate problems. The exception can be passed.
The result of execution failure is to exit directly .... Suppose you need to handle an exception (or an execution error):
--Displays an error message in the user interface.
However, this exception is thrown by the underlying API, such as a database call, and the client does not have permission to invoke the API directly.
At this point, you can choose:
- Throws an exception, one layer at a level throws
- Define the error code, one layer at a level back
You pick 2,
- finds that each function adds an incoming parameter called err, which is not used as an egg because it is returned to the previous layer without processing, directly to the UI.
- There's nothing wrong with that, but one day you're told that some underlying change is causing the API to throw a new error, and the boss asks you to dispose of the error on a layer in the call stack. Then you add a judgment on the type of the exception.
- Later, another new module needs to reuse the exception information you wrote in the module you were working on, and you encapsulate the exception information as an error class in order not to c&p the code, and each subclass that inherits from the error holds its own unique exception information.
- You are satisfied with the wheel you made, and then you use the module that is now maintained--now your code looks like this:
def f (Err, **kwargs): result = None if (Err.code = = 1): Handle_this_err (Err) elif (er R.code = = 2): Return (err, result) Else:result = Handle_data (**kwargs) return (None, result)
cross-function Number error code. Force error checking. happen path simplification. The last one, you have to write code that is exceptionally secure.
-