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
}
}
しかし、これらの構造にテンプレートまたは trait オブジェクトを介してどのように特徴を作成できますか? が存在するため、次の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
new を構築するときに の型を再帰的に割り当てる必要があるためです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からの関連付けられた型の実装を除いて、このように動作することも問題ありません。コアとなるアイデアは、トレイトでの再帰的な型宣言を避けることです。
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,
}