impl TraitX for TraitY
を動的サイズ型 (DST)TraitY
として使用しています。必要なライフタイム バウンドを追加すると (たとえば、ライフタイム バウンドの必要性に関する詳細については、こちらを参照してください)、コンパイラは次のように文句を言います。
trait TraitX { }
trait TraitY { }
impl<'a> TraitX for TraitY+'a { }
fn main() {}
<anon>:3:1: 3:34 error: the trait `core::kinds::Sized` is not implemented for the type `TraitY+'a`
<anon>:3 impl<'a> TraitX for TraitY+'a { }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:3:1: 3:34 note: the trait `core::kinds::Sized` must be implemented because it is required by `TraitX`
<anon>:3 impl<'a> TraitX for TraitY+'a { }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ベビーサークル
エラーは、サイズが指定TraitY+'a
されていないことを示しています。つまり、コンパイル時に既知のサイズがありません (たとえばu8
、サイズが 1 で、Vec<T>
3 つのポインターのサイズです)。
構文は特性オブジェクト(参照の「オブジェクト型」セクションTraitX
で説明されています) に対して実装されており、値の実装が期待される場所で (ポインターの背後で) 処理できるようになっています。作業用法には、いくつかの追加の注釈が含まれます。これらは、それらが添付されているものはすべて、オプションで ( ) サイズ設定されていることを示しています (デフォルトでは、サイズが設定されていると想定されます)。TraitY
TraitX
Sized?
?
#![allow(dead_code)]
// indicate that it's OK to implement this trait for DSTs
trait TraitX for Sized? { }
trait TraitY { }
trait TraitZ { }
impl<'a> TraitX for TraitY+'a { }
// the Sized? is to allow DSTs to be passed to this.
fn example<Sized? T: TraitX>(_: &T) {}
fn call_it(x: &TraitY, _y: &TraitZ) {
example::<TraitY>(x); // only possible if `TraitY` impls `TraitX`.
// error:
// example::<TraitZ>(_y); // `TraitZ` doesn't impl `TraitX`.
}
fn main() {}
ベビーサークル
現時点では、サイズのない型で関数を呼び出す場合は明示的な::<TraitY>
型ヒントが必要ですが、これはバグ#17178です。今のところ、DST にはまだかなりのバグがあるため、実際に使用するのは簡単ではありませんが、これは改善されるでしょう。
DST の主な動機は、トレイト オブジェクトの処理を他のポインター型とより一貫性のあるものにすることです。たとえば、現在は&Trait
とトレイト オブジェクトのみをサポートしていますが、DST は 、 などの他のポインター型を許可するようにBox<Trait>
設計されています。DST では、それらを実際のポインターのように扱うこともできます。たとえば、DST でのみ可能になった場合、以前はトレイト オブジェクトが通常のポインターではなくファット ポインターであるため、違法でした。Rc<Trait>
Arc<Trait>
obj: Box<Trait>
&*obj