如何将特征的实现拆分为多个文件?
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
块。但是即使那样你也不能多次实现相同的专业化。)
如果您想将 功能 拆分到单独的文件中,您可以这样做,但方式与您最初想的略有不同。您可以拆分 Client
的 impl
块而不是 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(())
}
}
我开始在多个文件中使用 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
块。但是即使那样你也不能多次实现相同的专业化。)
如果您想将 功能 拆分到单独的文件中,您可以这样做,但方式与您最初想的略有不同。您可以拆分 Client
的 impl
块而不是 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(())
}
}