When defining a trait, my understanding is that trait names on the right side of the :
are required any time the left side is implemented. If so, why does the following compile:
use std::any::Any;
trait Trait: Any {}
struct Thing {}
impl Trait for Thing {}
The following does not compile (which matches my understanding of what is correct)
trait RequiredTrait {}
trait Trait: RequiredTrait {}
struct Thing {}
impl Trait for Thing {}
Implementing a trait on a type is similar to implementing regular methods. The difference is that after impl , we put the trait name we want to implement, then use the for keyword, and then specify the name of the type we want to implement the trait for.
A trait tells the Rust compiler about functionality a particular type has and can share with other types. Traits are an abstract definition of shared behavior amongst different types. So, we can say that traits are to Rust what interfaces are to Java or abstract classes are to C++.
Traits can't have fields. If you want to provide access to a field from a trait, you need to define a method in that trait (like, say, get_blah ).
What are blanket implementations? Blanket implementations leverage Rust's ability to use generic parameters. They can be used to define shared behavior using traits. This is a great way to remove redundancy in code by reducing the need to repeat the code for different types with similar functionality.
std::any
contains the implementation:
impl<T> Any for T
where
T: 'static + ?Sized,
That means that any type implements Any
as long as any references it contains are 'static
and the type is sized. Your Thing
struct meets both of those requirements so it does implement Any
and your code compiles.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With