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

How to split an implementation of a trait into multiple files?

我开始在多个文件中使用 ws, and I would like to split the Handler 特征实现。

所以我把这个写在一个文件里,on_open.rs:

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

这在另一个文件中,on_message.rs:

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

编译时出现以下错误:

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

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

尽管同一个对象可以有多个impl块,但不能有两个完全相同的块,因此会出现[=32]的错误=]冲突的实现由E0119表示:

Since a trait cannot be implemented multiple times, this is an error.

(如果特征可以 specialised 因为它接受任意数量的泛型类型参数,情况会非常不同,因为每个专业化都会不同 impl块。但是即使那样你也不能多次实现相同的专业化。)

如果您想将 功能 拆分到单独的文件中,您可以这样做,但方式与您最初想的略有不同。您可以拆分 Clientimpl 块而不是 Handler 实现,如以下最小且可编译的示例所示。 (在 playground 试试吧!)

如你所见,Handler trait 是在一个地方为 Client 实现的,但是 Client 的所有实现都被拆分为多个 files/modules 和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(())
            }
        }
    }
}

感谢@Peter 的回答,我重新编写了如下代码,并且运行良好: socket.rs

use ws::Handler;
use crate::models::client::Client;
use ws::{Message, Request, Response, Result, CloseCode, Handshake};

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

    fn on_message(&mut self, msg: Message) -> Result<()> {
        self.handle_on_message(msg)
    }

    fn on_close(&mut self, code: CloseCode, reason: &str) {
        self.handle_on_close(code, reason)
    }

    fn on_request(&mut self, req: &Request) -> Result<(Response)> {
        self.handle_on_request(req)
    }
}

sockets/on_open.rs

use crate::models::client::Client;

use crate::CLIENTS;
use crate::models::{truck::Truck};
use ws::{Result, Handshake};

impl Client {
    pub fn handle_on_open(&mut self, _: Handshake) -> Result<()> {
        println!("socket is opened");
        Ok(())
    }
}