Traits
https://doc.rust-lang.org/reference/items/traits.html
Traits denote common behavior types can have (compare with interfaces in other languages):
#![allow(unused)] fn main() { trait DoubleSelf { fn double_self(&mut self); } }
You can implement:
- one of your traits on anyone's type
- anyone's trait on one of your types
- but not a foreign trait on a foreign type
Implementing foreign traits on foreign types is called creating "orphan instances", and is generally considered a bad thing.
Here's an implementation of our trait on a type:
#![allow(unused)] fn main() { impl DoubleSelf for i32 { fn double_self(&mut self) { self = self * 2; } } }
The Rust standard library has a couple traits that don't have any methods, these are called "marker traits" and usually denote some features of a type. For example:
Copymeans "use copy semantics on instances of this type" (like C language)Sendmeans "this type is safe to send to another thread"
Trait methods can also take self by reference or mutable reference:
#![allow(unused)] fn main() { // the clone trait explicitly creates a copy of an instance from reference impl Clone for Point { fn clone(&self) -> Self { Self { self.x, self.y } // floats are copy so we can use that } } }
The dot syntax implicitly borrows self where applicable so that you don't have to
do things like (&self).my_method().
Some common traits can be automatically implemented on your type by using a derive attribute:
#![allow(unused)] fn main() { #[derive(Clone, Copy)] struct MyStruct; }