diff --git a/examples/generics.rs b/examples/generics.rs index f575c559a6ebdd9cfe9962150bdd2368b97752d8..54e2e2bf540b8bb57eb251918b39b01ed27b119a 100644 --- a/examples/generics.rs +++ b/examples/generics.rs @@ -4,6 +4,8 @@ struct P<T> { y: T, } +// We can implement functions for +// instances of our generic type impl P<u32> { fn double(&mut self) { self.x += self.x; @@ -11,6 +13,7 @@ impl P<u32> { } } +// Another implementation impl P<u64> { fn double(&mut self) { self.x += self.x; @@ -26,10 +29,19 @@ fn main() { let mut p2 = P { x: 1u64, y: 2 }; p2.double(); println!("x {} y {}", p2.x, p2.y); + + let mut p3: P<u8> = P { x: 1u8, y: 2 }; + // p3.double(); // we don't have an implementation (yet) + println!("x {} y {}", p3.x, p3.y); } // The types of p1 and p2 is known at compile time -// (See that rust analyses derives the types) +// (See that rust analyzer derives the types.) // // The compiler will "specialize" the call // to double (as cheap as an ordinary call) +// +// We have a zero-cost abstraction. +// +// (We cannot do double on p3, as we don't have any +// implementation of double for P<u8>.) diff --git a/examples/traits.rs b/examples/traits.rs new file mode 100644 index 0000000000000000000000000000000000000000..beac5d8e532124fab7104cab6e339224cf169a1f --- /dev/null +++ b/examples/traits.rs @@ -0,0 +1,46 @@ +// a struct with generics +// a trait for double + +use std::fmt::Debug; + +#[derive(Debug)] +struct P<T> { + x: T, + y: T, +} + +// Declare an "interface", for double. +trait Double { + fn double(&mut self); +} + +// Implement Double for some types. +impl Double for P<u32> { + fn double(&mut self) { + self.x += self.x; + self.y += self.y; + } +} + +impl Double for String { + fn double(&mut self) { + let s = self.clone(); + self.push_str(&s); + } +} + +fn main() { + let mut p1 = P { x: 1u32, y: 2 }; + p1.double(); + println!("{:?}", p1); + + let mut s = "String, ".to_string(); + s.double(); + println!("{:?}", s); +} + +// Types of p1 and s is known at compile time +// Even if we now use Traits the compiler can +// specialize the calls to double. +// +// We have a zero-cost abstraction.