1

我有以下代码(受限示例)。有一个串行协议,使用crate 建模Command和枚举- 枚举中的每个变体都用一个结构表示。struct 任务负责 s 的序列化、执行和反序列化,用通用枚举(generic impl)或特定结构(templated impl)返回s。通用实现工作得很好,但模板化的实现无法编译。Responceenum_dispatchTransportCommandTransportResultResponce

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> {
       //..
   }
}
4

0 回答 0