首先,我知道Box
如果我想定义一个递归结构,我可以使用。例如,
struct LinkNode {
next: Option<Box<LinkNode>>
}
impl LinkNode{
fn get_next(&self) -> Option<Box<LinkNode>>{
None
}
fn append_next(&mut self, next: LinkNode) -> Self{
self
}
}
但是如何通过模板或特征对象在这些结构上创建特征?由于 的存在fn append_next(...) -> Self
,我不能像这样直接创建特征对象:
pub trait Linkable {
fn get_next(&self) -> Option<Box<dyn Linkable>>;
fn append_next(&mut self, next: impl Linkable) -> Self;
}
而且我们不能退货Option<Box<impl Linkable>>
或impl Linkable
换货fn get_next(&self)
。
然后我通过通用模板尝试了以下实现,但它不起作用。因为我需要T
在构造一个新的LinkNode
.
pub trait Linkable<T:Linkable<T> + Clone> : Clone {
fn get_next(&self) -> Option<Box<T>>;
fn append_next(&mut self, next: T) -> Self;
}
我最终以这种方式实现它,通过创建其他特征来提供帮助。而且效果很好。再次......还有其他更好的方法吗?
pub trait Linkable: LinkClone{
fn get_next(&self) -> Option<Box<dyn Linkable>>;
}
pub trait LinkAppend {
fn append_next(&mut self, next: Box<dyn Linkable>) -> Box<dyn Linkable>;
}
pub trait LinkClone{
fn clone_box(&self) -> Box<dyn Linkable>;
}
impl<T> LinkClonefor T
where
T: 'static + Linkable+ LinkAppend + Clone,
{
fn clone_box(&self) -> Box<dyn Linkable> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn Linkable> {
fn clone(&self) -> Box<dyn Linkable> {
self.clone_box()
}
}
顺便说一句,在上面的探索过程中我还有一些其他问题:为什么 Rust 禁止impl Linkable
糖,比如Box<impl Linkale>
? 为什么impl Linkable
在一个特征中禁止返回?
在Ibraheem的回答之后更新:
除了来自Ibraheem的关联类型实现之外,像这样工作也很好。核心思想是避免 trait 中的递归类型声明。
pub trait Linkable {
fn get_next<T:Linkable>(&self) -> Next<T>;
fn append_next<T:Linkable>(&mut self, next: Next<T>) -> Self;
}
struct Next<T: Linkable> {
node: T,
}