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



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

所以我把它写在一个文件中,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`:
--> srcsocketson_message.rs:9:1
|
9 | impl Handler for Client {
| ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `models::client::Client`
|
::: srcsocketson_open.rs:8:1
|
8 | impl Handler for Client {
| ----------------------- first implementation here

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

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

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

(如果特征可以专业化,因为它需要任意数量的泛型类型参数,那么情况将大不相同,因为每个特化都将是一个不同的impl块。 但是,即便如此,您也无法多次实施相同的专业化。

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

如您所见,Handlertrait 在一个地方实现了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(())
}
}
}
}

感谢您@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(())
}
}

最新更新