Traits

Declared like an implementation, but with no function bodies. Can have a body, which becomes the default implementation. Like C# abstract classes.

#![allow(unused)] fn main() { trait DoAThing { fn do_the_thing(&self) -> String; } impl DoAThing for u8 { fn do_the_thing(&self) -> String { format!("The thing is done for {:?}", &self); } } }

You can implement external traits on internal types, and internal traits on external types, but not external traits on external types.

Traits as function parameters is a bit weird. We have to use &impl DoAThing instead of just the trait name.

#![allow(unused)] fn main() { fn process_doers(thing: &impl DoAThing) -> String { thing.do_the_thing() } }

The above is syntactic sugar for (trait bound syntax):

#![allow(unused)] fn main() { fn process_doers<T: DoAthing>(thing: &T) -> String {} }

I think I prefer the trait bound syntax.