まだ時間がなくて詳しくは調べてないけど、こういう書き方はできない。まあそうかなと思う。
use std::fmt::Display; struct S<T> (T); fn main() { let s: Box<S<dyn Display>> = Box::new(S("")); }
Compiling playground v0.0.1 (/playground) error[E0277]: the size for values of type `dyn std::fmt::Display` cannot be known at compilation time --> src/lib.rs:6:12 | 3 | struct S<T> (T); | ---------------- required by `S` ... 6 | let s: Box<S<dyn Display>> = Box::new(S("")); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `dyn std::fmt::Display` = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait> error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. error: could not compile `playground`. To learn more, run the command again with --verbose.
S
をとっぱらって Box
で直接包むと Sized
扱いになるのでコンパイルできる。 これは、 Box
がコンパイラに特別視されてるからなのかな?
2020-05-23 追記
型変数がデフォルトで Sized
なのが原因だった。 ?Sized
を明確に指定すれば問題ない。
use std::fmt::Display; struct S<T> (T) where T: ?Sized; fn main() { let _s: Box<S<dyn Display>> = Box::new(S("")); }
Box
も 特別ではない 。
pub struct Box<T: ?Sized>(Unique<T>);