私は基本的には同等の2つの特性を持っていますが、どちらか一方が他方より低いレベルのインターフェースを提供します。より高いレベルの形質が与えられれば、より低いレベルの形質を容易に実現することができる。どちらの形質の実装を受け入れるライブラリを作成したいと思います。潜在的にカルにここ"シンプル"と "アドバンス"バージョンの錆特性
// "Lower level" version of the trait
pub trait RawState {
type Cost: std::cmp::Ord + std::ops::Add<Output = Self::Cost> + std::marker::Copy;
type CulledChildrenIterator: Iterator<Item = (Self, Self::Cost)>;
fn cull(&self) -> Option<Self::Cost>;
fn children_with_cull(&self) -> Self::CulledChildrenIterator;
}
// "Higher level" version of the trait
pub trait State: RawState {
type ChildrenIterator: Iterator<Item = (Self, Self::Cost)>;
fn children(&self) -> Self::ChildrenIterator;
}
// Example of how RawState could be implemented using State
fn state_children_with_cull<S: State> (s: S)
-> impl Iterator<Item = (S, S::Cost)>
{
s.children()
.filter_map(move |(state, transition_cost)|
state.cull().map(move |emission_cost|
(state, transition_cost + emission_cost)
)
)
}
は、国家の形質はあなたが.children()子どもの一覧を表示する機能を定義するインターフェイスを提供し、そして.cull()
機能:
私の特定のケースでは、ツリーをトラバースするための形質であります状態。
特性は.children_with_cull()
の代わりに関数を定義するインターフェースを提供します。このインターフェースでは、子を反復して1回の関数呼び出しでそれらを切り捨てます。これにより、RawState
の実装では、それが判明する子を生成することさえありません。
ほとんどのユーザーはState
特性のみを実装し、RawState
の実装はState実装に基づいて自動的に生成されるようにしたいと考えています。しかしながら、State
を実施する場合、形質の一部は依然としてRawState
の一部である。
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
struct DummyState {}
impl State for DummyState {
type Cost = u32;
type ChildrenIterator = DummyIt;
fn emission(&self) -> Option<Self::Cost> {
Some(0u32)
}
fn children(&self) -> DummyIt {
return DummyIt {};
}
}
"コスト"タイプが州ではなくRawStateで定義されているため、エラーが発生します。潜在的な問題を回避するには、すなわち、国家内部のRawStateのすべての関連する部分を再定義する
pub trait State: RawState {
type Cost: std::cmp::Ord + std::ops::Add<Output = Self::Cost> + std::marker::Copy;
type ChildrenIterator: Iterator<Item = (Self, Self::Cost)>;
fn cull(&self) -> Option<Self::Cost>;
fn children(&self) -> Self::ChildrenIterator;
}
として国家を定義しかし、その後、コンパイラはあいまいな重複定義文句を言うでしょう。たとえば、のDummyState
の実装では、<Self as State>::Cost
または<Self as RawState>::Cost
を参照しているかどうかを判断できないため、Self::Cost
はあいまいです。
「デフォルト実装」(https://doc.rust-lang.org/book/traits.html#default-methods)の「children_with_cull」を持つ1つの特性だけでなく、2つの特性が必要ですか? – trentcl
@trentcl: 'RawState'を直接実装するタイプのものは、' children'が直接使われていなくても 'children'を実装する必要があります。 –