感觉就像决定是否使用恐慌!或useResult<T,E>是任意的。任何地方都恐慌!宏最终被调用,比如试图除以零或试图访问越界的索引,我们可以返回一个Result<T,E>示例,并将错误处理责任留给用户(调用代码)。在访问向量中的越界索引的情况下,为什么不使用像 &v[100] 这样的正常索引代码,就像 v.get(100) 对于长度为5的向量 v 一样。我认为在所有情况下返回一个Result<T,E>会使代码变得有点麻烦,到处都是匹配表达式,但是感觉在保证恐慌的场景和保证返回Result<T,E>示例的场景之间没有明确的界限。
我试着在互联网上找到这个问题的答案,但到处都是这样的说法--如果一段代码使你的系统进入无效状态,或者如果它导致了一个不可恢复的错误,你应该恐慌。但究竟什么错误是不可恢复的呢?访问一个索引超出范围或除以零并不是不可恢复的,我们可以返回Result<T,E>,并将恢复责任留给用户。match表达式将确保用户处理所有可能性,尤其是错误。
这个错误处理决策归结起来有什么问题?它是否可以归结为务实的决定,如:这种错误有多罕见?是否频繁(正常)到足以保证将操作的返回类型从简单类型T更改为Result<T,E>,在此情况下,您必须执行额外的步骤来简单地取出数据?我们希望代码中的匹配表达式有多混乱?
2条答案
按热度按时间2nc8po8w1#
如果问题是算法固有的(即index out of bounds),那么我们应该重新编写代码,因此
panic!()
是有意义的:没有合理的理由使用带有不正确索引的[]
。另一方面,当错误可能是由于外部因素造成的,算法无法使任何事情变得更好(文件未找到,权限被拒绝......),那么应该使用
Result
报告错误,以便提供替代方案(给予,重试......)。omhiaaxx2#
确实,什么是可恢复/不可恢复的错误很难定义,并且在解释Rust中不同的错误处理策略时经常被跳过。我建议阅读一篇优秀的博客文章Using unwrap() in Rust is Okay。TL;DR是当错误意味着程序中有bug(由调用者或调用者引起)时使用 panic,否则返回
Result
。