16

以下のコードでは、同じ特性を実装する動的サイズの型への参照から特性オブジェクトへの参照を取得することはできません。これはなぜですか?&dyn Trait&(?Sized + Trait)両方を使用してトレイト メソッドを呼び出すことができる場合の違いは何ですか?

実装する型は、FooTraitContainerTraitたとえば havetype Contained = dyn FooTraitまたはtype Contained = Twhere Tis を実装する具体的な型である可能性がありますFooTrait。どちらの場合も、 を取得するのは簡単&dyn FooTraitです。これが機能しない別のケースは考えられません。の一般的なケースでこれが可能でないのはなぜFooTraitContainerTraitですか?

trait FooTrait {
    fn foo(&self) -> f64;
}

///

trait FooTraitContainerTrait {
    type Contained: ?Sized + FooTrait;
    fn get_ref(&self) -> &Self::Contained;
}

///

fn foo_dyn(dyn_some_foo: &dyn FooTrait) -> f64 {
    dyn_some_foo.foo()
}

fn foo_generic<T: ?Sized + FooTrait>(some_foo: &T) -> f64 {
    some_foo.foo()
}

///

fn foo_on_container<C: FooTraitContainerTrait>(containing_a_foo: &C) -> f64 {
    let some_foo = containing_a_foo.get_ref();
    // Following line doesn't work:
    //foo_dyn(some_foo)
    // Following line works:
    //some_foo.foo()
    // As does this:
    foo_generic(some_foo)
}

行のコメントを外すfoo_dyn(some_foo)と、コンパイラ エラーが発生する

error[E0277]: the size for values of type `<C as FooTraitContainerTrait>::Contained` cannot be known at compilation time
  --> src/main.rs:27:22
   |
27 |     foo_dyn(contained)
   |             ^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `<C as FooTraitContainerTrait>::Contained`
   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
   = help: consider adding a `where <C as FooTraitContainerTrait>::Contained: std::marker::Sized` bound
   = note: required for the cast to the object type `dyn FooTrait`
4

3 に答える 3