Sized and ?Sized

Every type in Rust must have a statically known sized. So every type is implemented Sized trait automatically. However there are sometime you need a DST(Dynamic Size Type), so you can use the special keyword ?Sized to indicate that you accept a DST type: T: ?Sized .

Drop

Rust will automatically called destructors of all type, most of the time, we don’t have to implement Drop in most cases. When we implemented a Drop trait, rust will called the Drop::drop method first, then drop the variable.

There are a cases that need to be remembered: when a value is drop with custom code, it means that the Drop::drop method is called. However the Drop::drop method take parameter &mut self, so there might be some lifetime conflict for customized destructor.

Subtyping

The reason that Rust don’t accept a child trait to be accepted in function which needs parent trait is the subtyping will lead to undefined behavior.

trait Animal {
    fn snuggle(&self);
    fn eat(&mut self);
}

trait Cat: Animal {
    fn meow(&self);
}

trait Dog: Animal {
    fn bark(&self);
}

fn love(pet: Animal) {
    pet.snuggle();
}

// This should be acceptable....?
let mr_snuggles: Cat = ...;
love(mr_snuggles);

//----------

fn evil_feeder(pet: &mut Animal) {
    let spike: Dog = ...;

    // `pet` is an Animal, and Dog is a subtype of Animal,
    // so this should be fine, right..?
    *pet = spike;
}

// No it is not acceptable
let mut mr_snuggles: Cat = ...;
evil_feeder(&mut mr_snuggles);  // Replaces mr_snuggles with a Dog
mr_snuggles.meow();

Where is subtyping

The most usual way to use subtyping is lifetime. When lifetime 'b contains lifetime 'a, we can say 'b is a subtype of the lifetime 'a. To understand this rule, think of this sentence: “object live in lifetime 'a live in lifetime 'b too. This can also be understood by the above relationship that represented by Cat Dog Animal. Also it is important to note that 'static is a subtype for every lifetime.