| As you say, the API feels similar. However, result types have many benefits over exceptions, with a few drawbacks. With a result type, in most languages, you can't just ignore failure. You must handle it, if you want to access the value. This prevents the common Java bug where a checked exception is caught but not handled. In rust, you must handle the error, propagate the error, or panic and fail fatally. Results don't abuse a runtime either. The exception process is slow - stack traces must be generated and the runtime itself needs to manually find the catch block responsible. Returning a result doesn't find this problem. Checked exceptions are fine for exceptional cases. At risk of sounding facetious, that's why they're called exceptions. But there's an important distinction that we need to make: logic failures are not exceptional. If you expect an operation may produce an error, you should handle it or crash the program. You should do this without incurring a performance hit, and using reliable and transparent primitives. Result types achieve both of these criteria, checked exceptions neither. The drawback to results is mainly the loss of data. Generating a stack trace is expensive, but often that's a worthwhile cost. Exceptions could be more versatile, in that any part of your code can throw any type of exception, but a result can only contain a specific type of error. That's not always a pro, though. So in general, checked exceptions are pretty awful for expressing normal failure cases, such as not finding a record in a database. They aren't great for anticipated errors, such as not finding a file, because of the chance a programmer might allow this to silently fail. Runtime exceptions are highly valuable, however. [1] - A decent SO post on the topic: https://stackoverflow.com/questions/613954/the-case-against-... |
How does the Rust way avoid this? You can just as easily match on an error type with a catch-all case and ignore the error.