lje*_*drz 5 error-handling rust
我最近实现了国际象棋游戏的基本机制,并将该Result<T, E>类型用于收集人类输入的方法,因为它可能无效.但是,我不确定我应该选择哪种类型的可能错误(E).
我认为在构建图书馆时,引入新类型被认为是一种很好的做法.但是,当Result可以立即处理并且Err在stdout中报告时,仅仅返回Result<T, String>s或Result<T, &str>s(或者Result<T, Cow<str>>如果两者都可以发生则更简单)是不是更简单?
考虑以下情况:
pub fn play() {
let mut game = Game::new();
loop {
match game.turn() {
Ok(()) => { game.turn += 1 }
Err(e) => println!("{}", e)
}
}
}
Run Code Online (Sandbox Code Playgroud)
游戏在终端中播放,可以立即报告任何输入错误.在这种情况下引入自定义错误类型是否有任何附加价值?
Luk*_*odt 10
这是一个相当广泛的问题,并没有明确的"正确"或"错误"答案.
在您的示例中需要注意的是,字符串带有非常容易访问的语义信息.当然,您可以通过解析字符串来提取所有语义信息,但这确实是错误的方法.因此,大多数较大的库或应用程序使用带有更多语义信息的错误类型,以便于错误处理.
在你的情况下,字符串可能没问题,如果你打算立即打印它们.但是有一个巧妙的小伎俩,以便至少使函数签名更具有未来的证据:返回Box<Error>.
的Error特点是在错误的一个很好的抽象.几乎每个错误类型都实现了这个特性.随着try!()和Into特点,它可以处理大多数错误自如.此外:impl字符串和字符串有一些类型转换Box<Error>.这允许将字符串作为错误返回:
fn foo() -> Result<(), Box<Error>> {
try!(std::fs::File::open("not-here")); // io::Error
try!(Err("oh noooo!")); // &str
try!(Err("I broke it :<".to_owned())); // String
Err("nop".into())
}
Run Code Online (Sandbox Code Playgroud)
查看工作演示.
编辑:请注意,它Box<Error>比其他具体错误类型携带更少的语义信息io::Error.所以总是回来不是一个好主意Box<Error>!在你的情况下,这只是一个更好的方法:)
编辑2:我最近在错误处理模型上阅读了很多,这改变了我的观点.我仍然认为这个答案非常正确.但是,我认为到目前为止,这并不像我在这里制定的那么容易.所以,一定要记住这个答案不适合作为一般的指导可言!
| 归档时间: |
|
| 查看次数: |
595 次 |
| 最近记录: |