我很難嘗試創建一個通用的錯誤類型,但它不會轉化爲impl
和泛型參數的混亂。創建簡潔和通用錯誤類型時遇到問題
我有分系統的幾個通用參數的結構,每個已返回自定義錯誤類型的方法:
struct App<A: ..., B: ..., ...> {
a: A,
b: B,
...
}
impl<A: ..., B: ..., ...> App<A, B, ...> {
fn do_something_cross_cutting(&self) -> Result<(), AppError> {
a.run()?;
b.run()?;
Ok(())
}
}
應該如何AppError
被幹淨定義?起初,我嘗試使用quick_error!
像這樣:
quick_error! {
#[derive(Debug)]
enum AppError<A: ..., B: ..., ...> {
AError(err: A::Error) {
from()
display(...)
}
BError(err: B::Error) {
from()
display(...)
}
...
}
}
但quick_error!
似乎不支持通用枚舉。此外,由於AppError
現在是通用的和看起來好像不可能在impl
塊中定義類型別名,每種可能失敗的方法都會有非常廣泛的返回類型(Result<_, AppError<A, B, ...>>
)。
quick_error!
可以避免,但同樣以犧牲可讀性和代碼大小爲代價,並且它不能解決第二個問題。
我想出了以下替換,但不編譯:
quick_error! {
#[derive(Debug)]
enum AppError {
AError(err: Box<Error>) {
display(...)
}
BError(err: Box<Error>) {
display(...)
}
...
}
}
impl<A: ...> From<A::Error> for AppError {
fn from(err: A::Error) -> Self {
AppError::AError(Box::new(err))
}
}
...
rustc
抱怨與the type parameter `A` is not constrained by the impl trait, self type, or predicates
,我不知道如何解決它。
最後的可能性是最簡單的:簡單地傳播一個Box<Error>
。這是我的計劃B.最大的問題是有用的信息丟失了。通過定義AppError
(以及遞歸的子系統特定的錯誤類型),我得到了一個窮人的錯誤回溯。使用Box<Error>
會使錯誤難以追蹤。
有沒有其他的選擇,或者我接近這個錯誤的方式嗎?
關於你的追溯問題:你有沒有試過['error_chain'](https://crates.io/crates/error-chain)?它具有集成的回溯功能。 –
我來看看 – moatPylon