我有以下代码(受限示例)。有一个串行协议,使用crate 建模Command
和枚举- 枚举中的每个变体都用一个结构表示。struct 任务负责 s 的序列化、执行和反序列化,用通用枚举(generic impl)或特定结构(templated impl)返回s。通用实现工作得很好,但模板化的实现无法编译。Responce
enum_dispatch
Transport
Command
TransportResult
Responce
use enum_dispatch::enum_dispatch;
use thiserror::Error;
trait Value{/**/}
trait CommandResponce {type Responce}
#[enum_dipatch(Value)]
enum Command{
Cmd1(Cmd1)
// ...
}
struct Cmd1{}
impl Value for Cmd1{ /**/ }
#[enum_dipatch(Value)]
enum Responce{
Resp1(Resp1)
// ...
}
struct Resp1{}
impl Value for Resp1{/**/}
impl CommandResponce for Cmd1{ type Responce=Resp1 }
#[derive(Error, Debug)]
pub enum ProtocolError{/**/}
type ProtocolResult<T> = Result<T, ProtocolError>;
struct Transport {/**/}
impl Transport {
// generic
pub fn command_generic_with_addr(
&mut self, addr: &mut u8, c: Command
) -> ProtocolResult<Responce>{ /**/ }
// templated
pub fn command_with_addr<T: SerializeCommand + CommandResponce>(
&mut self, addr: &mut u8, c: T) -> ProtocolResult<T::Responce>
where
Command: From<T>, Responce: TryInto<T::Responce, Error=&'static str>,
Responce: TryInto<T::Responce, Error= CommandErrors> {
let resp: Responce = self.command_generic_with_addr(addr, Command::from(c))?;
let ret: T::Responce = resp.try_into()?;
Ok(ret)
}
}
fn main() -> eyre::Result<()>{
let t = Transport::new();
let addr : u8 = 0xFF;
t.command_with_addr(&mut addr, Cmd1{/**/})
}
当我尝试编译与上面相同的代码时,我收到以下错误:
error[E0284]: type annotations needed: cannot satisfy `<Responce as TryInto<<T as CommandResponce>::Responce>>::Error == _`
-->
|
85 | let ret: T::Responce = match resp.try_into() {
| ^^^^^^^^ cannot satisfy `<Responce as TryInto<<T as CommandResponce>::Responce>>::Error == _`
我不明白,这里的错误是什么 - 我以为我已经在Transport::command_with_addr
成员函数中说明了所有必要的类型注释。
注意,enum_dispatch
使用以下代码生成try_into
转换,在上面的代码中使用:
impl #impl_generics core::convert::TryInto<#variant_type> for #enumname #ty_generics #where_clause {
type Error = &'static str;
fn try_into(self) -> ::core::result::Result<#variant_type, <Self as core::convert::TryInto<#variant_type>>::Error> {
//..
}
}