Skip to content

Latest commit

 

History

History
86 lines (67 loc) · 2.27 KB

Sized.md

File metadata and controls

86 lines (67 loc) · 2.27 KB

Table of contents


URLs

Trait URL
Sized std::marker::Sized

Declaration

pub trait Sized { }

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]`

?Sized

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 { }) requires Self: Sized;

Examples

Sized trait

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...

?Sized generic

struct Bar<T>(T) where T: ?Sized;
struct BarUse(Bar<[i32]>); // OK