Please let me know if this question is duplicated in somewhere else here.
I started learning Rust for a while, and understood what is struct and impl, similar to class and its methods in OOP languages.
Yet, I also often heard about trait, which I do not know, searched online but all I get is the topics assuming people who already knew what trait is, or are written for native English speakers (I'm not).
I think the most I get is from Rust By Example, which my own understanding is:
trait is used to define the methods that can be used for any struct, as an additional methods.
Correct me if I misunderstood the true meaning of using trait, and perhaps explain like I'm five . I'm very concern of understanding the common things well in Rust. Thank you.
The closest matching description of a trait from OOP world could be interface but which allows implementation and overriding of some (or all) methods within the trait.
trait HasVoice {
fn speak(&self) {} // No implementation
fn shout(&self) {
println!("Base shout!");
}
}
struct Foo {}
impl HasVoice for Foo {
// Can reuse shout from the default implementation inside HasVoice
// Or provide it's own too.
fn speak(&self) {
// Need to implement this as the trait does not provide default
// implementation
println!("Foo speak!");
}
}
struct Bar {}
impl HasVoice for Bar {
// In Bar, we override the default shout() implementation
fn shout(&self) {
println!("Custom bar shout!");
}
fn speak(&self) {
println!("Bar speak!");
}
}
pub fn main() {
let foo = Foo {};
foo.speak(); // Foo speak!
foo.shout(); // Base shout!
let bar = Bar {};
bar.speak(); // Bar speak!
bar.shout(); // Custom bar shout!
}
Traits can also be used as constraints upon generics. For example:
fn bar<T: HasVoice>(speaker: T) {
...
}
The compiler will error if the bar() is called with some T which does not impl HasVoice as we have constrained T in the definition (notice: <T: HasVoice>).