4

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)

次に、汎用テンプレートを介して次の実装を試みましたが、機能しません。Tnew を構築するときに の型を再帰的に割り当てる必要があるためです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,
}

これは別の質問で言及されています: Rust でそれ自体の型パラメーターを持つ特性を定義できますか?

4

1 に答える 1