如何将特征的实现拆分为多个文件?

Has*_*sef 5 module traits rust

我开始使用ws,我想将Handler特征实现拆分为多个文件。

所以我把这个写在一个文件中on_open.rs

impl Handler for Client {
    fn on_open(&mut self, _: Handshake) -> Result<()> {
        println!("Socket opened");
        Ok(())
    }
}
Run Code Online (Sandbox Code Playgroud)

这在另一个文件中on_message.rs

impl Handler for Client {
    fn on_message(&mut self, msg: Message) -> Result<()> {
        println!("Server got message '{}'. ", msg);
        Ok(())
    }
}
Run Code Online (Sandbox Code Playgroud)

编译时我收到以下错误:

error[E0119]: conflicting implementations of trait `ws::handler::Handler` for type `models::client::Client`:
 --> src\sockets\on_message.rs:9:1
  |
9 | impl Handler for Client {
  | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `models::client::Client`
  |
 ::: src\sockets\on_open.rs:8:1
  |
8 | impl Handler for Client {
  | ----------------------- first implementation here
Run Code Online (Sandbox Code Playgroud)

我希望将这些文件分开,以便每个开发人员都可以处理单独的文件。有没有办法实现这一点,或者我被迫在单个文件中实现完整的特征?

Pet*_*aro 8

impl虽然同一个对象可以有多个块,但不能有两个完全相同的块,因此会出现以下所示的冲突实现E0119错误:

由于一个特征不能被多次实现,所以这是一个错误。

(如果该特征可以被专门化,因为它需要任意数量的泛型类型参数,那么情况将会非常不同,因为每个专门化都将是不同的impl块。但是即使如此,您也无法多次实现相同的专门化.)

如果您想将功能拆分为单独的文件,您可以这样做,但方式与您最初想象的略有不同。您可以拆分Client'simpl块而不是Handler实现,如以下最小且可编译的示例所示。(在操场上尝试一下!)

正如您所看到的,该Handler特征是在一个地方实现的Client,但是所有的实现都Client被分成多个文件/模块,并且Handler实现只是引用这些:

mod handler
{
    pub type Result<T> = ::std::result::Result<T, HandlerError>;

    pub struct HandlerError;

    pub trait Handler
    {
        fn on_open(&mut self, h: usize) -> Result<()>;
        fn on_message(&mut self, m: bool) -> Result<()>;
    }
}

mod client
{
    use super::handler::{ self, Handler };

    struct Client
    {
        h: usize,
        m: bool,
    }

    impl Handler for Client
    {
        fn on_open(&mut self, h: usize) -> handler::Result<()>
        {
            self.handle_on_open(h)
        }

        fn on_message(&mut self, m: bool) -> handler::Result<()>
        {
            self.handle_on_message(m)
        }
    }

    mod open
    {
        use super::super::handler;
        use super::Client;

        impl Client
        {
            pub fn handle_on_open(&mut self, h: usize) -> handler::Result<()>
            {
                self.h = h;
                Ok(())
            }
        }
    }

    mod message
    {
        use super::super::handler;
        use super::Client;

        impl Client
        {
            pub fn handle_on_message(&mut self, m: bool) -> handler::Result<()>
            {
                self.m = m;
                Ok(())
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)