該函式預計將接受一個可以轉換為字串的命令,而且我正在使用無論如何處理錯誤的事情。這是代碼:
pub fn converter<T: TryInto<String>>(input: T) -> Result<String>
where
T::Error: Into<anyhow::Error>,
{
// error here
// the trait bound `<T as TryInto<std::string::String>>::Error: StdError` is not satisfied
// required because of the requirements on the impl of `From<<T as TryInto<std::string::String>>::Error>` for `anyhow::Error`
// required because of the requirements on the impl of `FromResidual<Result<Infallible, <T as TryInto<std::string::String>>::Error>>` for `Result<std::string::String, anyhow::Error>
let out_str = input.try_into()?;
Ok(out_str)
}
我為T::Erroras添加了型別限制T::Error: Into<anyhow::Error>,希望編譯器可以進行錯誤處理,但顯示T::Error無法轉換為anyhow::Error.
型別限制來自:https ://github.com/dtolnay/anyhow/issues/172 ,但我仍然無法弄清楚如何使用TryInto泛型。
uj5u.com熱心網友回復:
TL;DR:替換T::Error: Into<anyhow::Error>為anyhow::Error: From<T::Error>.
這個很微妙。
你可能已經預料到去糖?是這樣的(忽略像Try特征這樣的額外設施):
let out_str = match input.try_into() {
Ok(v) => v,
Err(e) => return Err(Into::into(e)),
};
但事實并非如此。相反,它更像是:
let out_str = match input.try_into() {
Ok(v) => v,
Err(e) => return Err(From::from(e)),
};
這會產生完全相同的錯誤。這是因為Result用于From轉換錯誤,而不是Into.
現在,擁有一個Fromimpl 意味著擁有一個Intoimpl——因為一攬子實作impl<T, U: From<T>> Into<U> for T——但相反的情況是不正確的,而且,對于當前的 Rust 特征系統來說,這不可能是正確的。
如果Result將Into在脫糖中使用,您會很好,因為編譯器可以T::Error: Into<anyhow::Error>從您的where子句中證明成立,但鑒于它使用From,編譯器無法證明anyhow::Error: From<T::Error>成立,因此會引發錯誤。
過去曾嘗試改變脫糖(#60796),但不幸的是它導致了太多的推理中斷,所以現在可能是不可能的。看:
- https://github.com/rust-lang/rust/issues/84277#issuecomment-903944296
- https://github.com/rust-lang/rust/issues/31436#issuecomment-299482914
- https://github.com/rust-lang/rust/issues/31436#issuecomment-619427209
- https://github.com/rust-lang/rust/issues/38751
uj5u.com熱心網友回復:
首先,您的示例缺少 a use anyhow::Result,因為Result沒有 a useis std::result::Result,它需要兩個通用引數。
它不編譯的原因是因為Into可以派生自From,但From不能派生自Into。并且?運營商似乎使用From.
編譯的版本:
where
T::Error: std::error::Error Send Sync 'static,
where
anyhow::Error: From<T::Error>,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/494527.html
下一篇:C#如何在代碼中動態實體化型別
