如果String可以在stdout中立即报告,它是一个有效的错误类型吗?

时间:2016-08-28 18:52:28

标签: error-handling rust

我最近实现了国际象棋游戏的基本机制,并使用Result<T, E>类型收集人类输入的方法,因为它可能无效。但是,我不确定我应该选择哪种类型的可能错误(E)。

我认为在构建图书馆时,引入新类型被认为是一种很好的做法。但是,如果可以立即处理Result并且在stdout中报告了Err,那么只返回Result<T, String>Result<T, &str> s(或{ {1}}如果两者都可以发生?)

考虑以下情况:

Result<T, Cow<str>>

游戏在终端播放,任何输入错误都可以立即报告。在这种情况下引入自定义错误类型是否有任何附加价值?

1 个答案:

答案 0 :(得分:8)

这是一个相当广泛的问题,没有明确的“正确”或“错误”答案。

在您的示例中需要注意的是,字符串带有很少的易于访问的语义信息。当然,您可以通过解析字符串来提取所有语义信息,但这确实是错误的方法。因此,大多数较大的库或应用程序使用带有更多语义信息的错误类型,以便于错误处理。

在你的情况下,字符串可能没问题,如果你打算立即打印它们。但是有一个巧妙的小技巧,以便至少使函数签名更具有未来性:返回Box<Error>

Error trait是一个很好的抽象错误。几乎每个错误类型都实现了这个特性。使用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())
}

请参阅working demo

编辑:请注意,Box<Error>的语义信息少于io::Error等其他具体错误类型。因此,始终返回Box<Error>并不是一个好主意!在您的情况下,这只是一种更好的方法:)

编辑2 :我最近在错误处理模型上阅读了很多,这改变了我的观点。我仍然认为这个答案非常正确。但是,我认为到目前为止,这并不像我在这里制定的那么容易。所以请记住,这个答案不适合作为一般指南在所有