包含相关类型(也是动态调度)的特征向量(动态调度)

时间:2016-02-16 17:43:46

标签: rust dynamic-dispatch

我有一个特点:

pub trait Plugin {
    type Error: error::Error;

    fn handle(&mut self, client: & Client, message: Message) -> Result<(), Self::Error>;
}

此特征有许多实现(每个实现包含特定的错误类型):

impl ::Plugin for first::Plugin {
    type Error = first::Error;

    fn handle(&mut self, client: & Client, message: Message) -> first::Result<()> {
        ...
        Ok(())
    }
}

impl ::Plugin for second::Plugin {
    type Error = second::Error;

    fn handle(&mut self, client: & Client, message: Message) -> second::Result<()> {
        ...
        Ok(())
    }
}

我需要创建插件矢量:

let mut plugins: Vec<Box<Plugin<Error=_>>> = vec![
    Box::new(first::Plugin::new()),
    Box::new(second::Plugin::new()),
];

但是代码抛出了这个错误:

error: type mismatch resolving `<plugins::first::Plugin<'_> as plugin::Plugin>::Error == plugins::second::error::Error`:

如何重新组织代码以创建包含关联类型(动态调度,impl trait Plugin)的插件向量(动态调度,impl trait error::Error)?

-

以下是完整的代码:

fn main() {
    let mut plugins: Vec<Box<Plugin<Error = _>>> = vec![
        Box::new(first::Plugin::new()),
        Box::new(second::Plugin::new()),
    ];
}

pub trait Plugin {
    type Error: std::error::Error;

    fn handle(&mut self) -> Result<(), Self::Error>;
}

mod first {
    use std;

    pub struct Plugin;

    impl Plugin {
        pub fn new() -> Plugin {
            Plugin
        }
    }

    impl ::Plugin for Plugin {
        type Error = Error;

        fn handle(&mut self) -> Result<(), Error> {
            Ok(())
        }
    }

    #[derive(Debug)]
    pub struct Error;

    impl std::fmt::Display for Error {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
            write!(f, "{}", "first error")
        }
    }

    impl std::error::Error for Error {
        fn description(&self) -> &str {
            "first error"
        }
    }
}

mod second {
    use std;

    pub struct Plugin;

    impl Plugin {
        pub fn new() -> Plugin {
            Plugin
        }
    }

    impl ::Plugin for Plugin {
        type Error = Error;

        fn handle(&mut self) -> Result<(), Error> {
            Ok(())
        }
    }

    #[derive(Debug)]
    pub struct Error;

    impl std::fmt::Display for Error {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
            write!(f, "{}", "second error")
        }
    }

    impl std::error::Error for Error {
        fn description(&self) -> &str {
            "second error"
        }
    }
}

Rust playground

0 个答案:

没有答案