您不能直接使用HStream 类型;它不代表任何东西。仅用于构造派生指针类型,如&HStream 和Box<HStream>。
最简单的解决方案是使用LinkedList 或Stream<Box<HStream>>。
fn main() {
let mut list = Arc::new(Mutex::new(LinkedList::<Stream<Box<HStream>>>::new()));
}
然后,我们只需为Box<HStream> 实现HStream。
impl<'a> HRecv for Box<HStream + 'a> {}
impl<'a> HSend for Box<HStream + 'a> {}
impl<'a> AsRawFd for Box<HStream + 'a> {
fn as_raw_fd(&self) -> RawFd { (&**self).as_raw_fd() }
}
impl<'a> HStream for Box<HStream + 'a> {}
请注意,这缺少一个特征...Clone。
Clone 不是对象安全的,这意味着无法为该 trait 创建 trait 对象类型,例如 &Clone 或 Box<Clone>。 Clone 不是对象安全的,因为它的clone 方法返回Self,它代表了实现者的具体类型。如果您通过 trait 对象使用此方法,编译器将无法提前知道结果的类型(可能是 Clone 的任何实现者!)。
由于HStream 是Clone 的子特征,HStream 也不是对象安全的。结果就是我们根本无法实现Clone,而Box<HStream>这样的类型是不合法的。
但是,我们可以通过创建自己的对象安全 trait 来解决这个问题。我们甚至可以在实现标准 Clone trait 的类型上自动实现它。
pub trait BoxedHStreamClone {
fn boxed_clone(&self) -> Box<HStream>;
}
// Implementation for all types that implement HStream and Clone and don't hold any borrows
impl<T: HStream + Clone + 'static> BoxedHStreamClone for T {
fn boxed_clone(&self) -> Box<HStream> {
Box::new(self.clone()) as Box<HStream>
}
}
// Implementation for Box<HStream + 'a>, which cannot implement Clone
impl<'a> BoxedHStreamClone for Box<HStream + 'a> {
fn boxed_clone(&self) -> Box<HStream> {
Box::new((&**self).boxed_clone()) as Box<HStream>
}
}
将绑定在HStream 上的Clone 特征替换为BoxedHStreamClone,就可以开始了!
pub trait HStream: HRecv + HSend + AsRawFd + BoxedHStreamClone {}
Here's the final code:
use std::sync::{Arc, Mutex};
use std::collections::LinkedList;
use std::os::unix::io::{RawFd, AsRawFd};
pub trait BoxedHStreamClone {
fn boxed_clone(&self) -> Box<HStream>;
}
impl<T: HStream + Clone + 'static> BoxedHStreamClone for T {
fn boxed_clone(&self) -> Box<HStream> {
Box::new(self.clone()) as Box<HStream>
}
}
pub trait HRecv {}
pub trait HSend {}
pub trait HStream: HRecv + HSend + AsRawFd + BoxedHStreamClone {}
pub struct Stream<T: HStream> {
pub inner: T
}
pub type StreamList = Arc<Mutex<LinkedList<Stream<Box<HStream>>>>>;
impl<'a> HRecv for Box<HStream + 'a> {}
impl<'a> HSend for Box<HStream + 'a> {}
impl<'a> AsRawFd for Box<HStream + 'a> {
fn as_raw_fd(&self) -> RawFd { (&**self).as_raw_fd() }
}
impl<'a> BoxedHStreamClone for Box<HStream + 'a> {
fn boxed_clone(&self) -> Box<HStream> {
Box::new((&**self).boxed_clone()) as Box<HStream>
}
}
impl<'a> HStream for Box<HStream + 'a> {}
fn main() {
let mut list = Arc::new(Mutex::new(LinkedList::<Stream<Box<HStream>>>::new()));
}