Trait | URL |
---|---|
Sized |
std::marker::Sized |
pub trait Sized { }
The Sized
trait is the marker trait and it indicates that the size of type is known at compile time.
The Sized
trait is implemented automatically by the compiler for most types. In other words, most of types have implicit Sized
bound by default.
Also Rust adds the Sized
bound to all generics (T: Sized
). In other words, any type parameter or associated type has implicit Sized
bound by default:
struct Foo<T>(T);
struct FooUse(Foo<[i32]>); // Error: the trait `Sized` is not implemented for `[i32]`
DST (dynamically sized types) are types that grow or shrink dynamically at runtime and their sizes are not known at compile time.
The special syntax ?Sized
is used to remove default Sized
bound. So, DST use ?Sized
bound.
Examples of DST:
Slice
;trait <name> {}
;String
;
So, a trait doesn't have an implicit Sized
bound as this is incompatible with trait objects.
Although Rust allows define Sized
traits, but such Sized
traits cannot be used as trait objects later.
Notation for defining Sized
traits: trait <name>: Sized { }
.
So,
Self
type of any trait is?Sized
by default;Sized
trait (trait <name>: Sized { }
) requiresSelf: Sized
;
trait Foo { }
trait Bar: Sized { }
struct Impl;
impl Foo for Impl { }
impl Bar for Impl { }
let x: &dyn Foo = &Impl; // OK
let y: &dyn Bar = &Impl; // Error
Error:
20 | trait Bar: Sized { }
| --- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
struct Bar<T>(T) where T: ?Sized;
struct BarUse(Bar<[i32]>); // OK