Is error handling in Rust all about when you can and can’t afford to return a Result<T,E> instance?

huangapple go评论72阅读模式
英文:

Is error handling in Rust all about when you can and can’t afford to return a Result<T,E> instance?

问题

感觉是否使用 panic! 或使用 Result<T,E> 的决定似乎有点随意。在任何调用 panic! 宏的地方,比如尝试除以零或尝试访问超出边界的索引,我们都可以返回一个 Result<T,E> 实例,将错误处理责任留给用户(调用代码)。在访问向量中超出边界的索引的情况下,为什么不让普通的索引代码像 &v[100] 一样,对于长度为5的向量 v,表现得像 v.get(100) 呢?我认为在所有情况下返回 Result<T,E> 会使代码变得有点繁琐,到处都是匹配表达式,但似乎没有明确的界限,来判断何时应该引发 panic,何时应该返回 Result<T,E> 实例。

我尝试在互联网上找到答案,但到处都是某种形式的回答 - 如果一段代码使系统进入无效状态,或者导致无法恢复的错误,那么你应该引发 panic。但是,什么样的错误是无法恢复的呢?访问超出边界的索引或除以零并不是无法恢复的,我们可以只返回 Result<T,E> 并将恢复的责任交给用户。匹配表达式将确保用户处理所有可能性,特别是错误的可能性。

这个错误处理决策涉及到哪些问题?它是否归结为实际决策,比如:
错误有多少稀有?它是否频繁(正常)到足以将操作的返回类型从简单类型 T 更改为 Result<T,E>,其中您必须执行额外的步骤才能简单地获取数据?我们希望我们的代码充斥着匹配表达式吗?

英文:

It feels like the decision of whether to use panic! or use Result<T,E> is kind of arbitrary. Any place where the panic! macro ends up being called, like trying to divide by zero or trying to access an index out of bounds, we could have returned a Result<T,E> instance instead and left the error handling responsibility to the user (the calling code). In the case of accessing an index out of bounds in a vector, why not have normal indexing code like &v[100] behave just like v.get(100) for a vector v of length 5. I reckon that returning a Result<T,E> in all situations would make the code a bit cumbersome with match expressions everywhere, but it feels like there's no clear line between the kind of scenarios that warrant panicking and those that warrant returning a Result<T,E> instance.

I've tried to find the answer to this on the internet but everywhere it states some version of - if a piece of code takes your system into an invalid state, or if it causes an unrecoverable error, you should panic. But what error is unrecoverable exactly? Accessing an index out of bounds or dividing by zero isn't unrecoverable by any means, we can just return Result<T,E> and leave the recovering responsibility to the user. The match expression is going to make sure that the user deals with all the possibilities, especially that of an error.

What concerns does this error handling decision boil down to? Does it boil down to pragmatic decisions like:
How rare is the error? Is it frequent (normal) enough to warrant changing the return type of an operation from a simple type T to Result<T,E> where you have to do extra steps to simply get out the data? How cluttered with match expressions do we want our code to be?

答案1

得分: 1

如果问题是算法固有的(即索引超出范围),那么我们应该重新设计代码,因此 panic!() 是有道理的:在使用不正确的索引时没有有效的理由使用 []

另一方面,当错误可能是由外部因素引起的,算法无法改善任何情况(文件未找到,权限被拒绝...)时,应该使用 Result 报告错误,以提供备选方案的可能性(放弃,重试...)。

英文:

If the problem is inherent to the algorithm (i.e. index out of bounds), then we should rework the code, thus panic!() makes sense: there is no valid reason to use [] with an incorrect index.

On the other hand, when the error can be due to an external factor, where the algorithm cannot make anything better (file not found, permission denied...) then the error should be reported with Result in order to offer the possibility of an alternative (give up, retry...).

答案2

得分: 0

以下是翻译好的部分:

"It is true that what constitutes an recoverable/unrecoveable error is hard to define and is often skipped when explaining different strategies of error handling in Rust. I would suggest reading an excellent blog post Using unwrap() in Rust is Okay. The TL;DR is to use panic when an error means that there is a bug in the program (caused by either caller or the callie) and returing Result otherwise."

英文:

It is true that what constitutes an recoverable/unrecoveable error is hard to define and is often skipped when explaining different strategies of error handling in Rust. I would suggest reading an excellent blog post Using unwrap() in Rust is Okay. The TL;DR is to use panic when an error means that there is a bug in the program (caused by either caller or the callie) and returing Result otherwise.

huangapple
  • 本文由 发表于 2023年6月6日 05:09:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76410033.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定