mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-01-07 08:45:24 +02:00
Cover Supertraits, Generic Traits (#1854)
This commit is contained in:
parent
d0656ca90b
commit
ac2cb44d54
@ -82,6 +82,7 @@
|
||||
- [Methods](methods-and-traits/methods.md)
|
||||
- [Traits](methods-and-traits/traits.md)
|
||||
- [Implmementing Traits](methods-and-traits/traits/implementing.md)
|
||||
- [Supertraits](methods-and-traits/traits/supertraits.md)
|
||||
- [Associated Types](methods-and-traits/traits/associated-types.md)
|
||||
- [Deriving](methods-and-traits/deriving.md)
|
||||
- [Exercise: Generic Logger](methods-and-traits/exercise.md)
|
||||
@ -89,6 +90,7 @@
|
||||
- [Generics](generics.md)
|
||||
- [Generic Functions](generics/generic-functions.md)
|
||||
- [Generic Data Types](generics/generic-data.md)
|
||||
- [Generic Traits](generics/generic-traits.md)
|
||||
- [Trait Bounds](generics/trait-bounds.md)
|
||||
- [`impl Trait`](generics/impl-trait.md)
|
||||
- [Exercise: Generic `min`](generics/exercise.md)
|
||||
|
52
src/generics/generic-traits.md
Normal file
52
src/generics/generic-traits.md
Normal file
@ -0,0 +1,52 @@
|
||||
---
|
||||
Minutes: 5
|
||||
---
|
||||
|
||||
# Generic Traits
|
||||
|
||||
Traits can also be generic, just like types and functions. A trait's parameters
|
||||
get concrete types when it is used.
|
||||
|
||||
```rust,editable
|
||||
#[derive(Debug)]
|
||||
struct Foo(String);
|
||||
|
||||
impl From<u32> for Foo {
|
||||
fn from(from: u32) -> Foo {
|
||||
Foo(format!("Converted from integer: {from}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bool> for Foo {
|
||||
fn from(from: bool) -> Foo {
|
||||
Foo(format!("Converted from bool: {from}"))
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let from_int = Foo::from(123);
|
||||
let from_bool = Foo::from(true);
|
||||
println!("{from_int:?}, {from_bool:?}");
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
- The `From` trait will be covered later in the course, but its
|
||||
[definition in the `std` docs](https://doc.rust-lang.org/std/convert/trait.From.html)
|
||||
is simple.
|
||||
|
||||
- Implementations of the trait do not need to cover all possible type
|
||||
parameters. Here, `Foo::From("hello")` would not compile because there is no
|
||||
`From<&str>` implementation for `Foo`.
|
||||
|
||||
- Generic traits take types as "input", while associated types are a kind of
|
||||
"output type. A trait can have multiple implementations for different input
|
||||
types.
|
||||
|
||||
- In fact, Rust requires that at most one implementation of a trait match for
|
||||
any type T. Unlike some other languages, Rust has no heuristic for choosing
|
||||
the "most specific" match. There is work on adding this support, called
|
||||
[specialization](https://rust-lang.github.io/rfcs/1210-impl-specialization.html).
|
||||
|
||||
</details>
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
minutes: 10
|
||||
minutes: 15
|
||||
---
|
||||
|
||||
# Traits
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Associated Types
|
||||
|
||||
Associated types are placeholder types which are filled in by the trait
|
||||
Associated types are placeholder types which are supplied by the trait
|
||||
implementation.
|
||||
|
||||
```rust,editable
|
||||
|
41
src/methods-and-traits/traits/supertraits.md
Normal file
41
src/methods-and-traits/traits/supertraits.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Supertraits
|
||||
|
||||
A trait can require that types implementing it also implement other traits,
|
||||
called _supertraits_. Here, any type implementing `Pet` must implement `Animal`.
|
||||
|
||||
```rust,editable
|
||||
trait Animal {
|
||||
fn leg_count(&self) -> u32;
|
||||
}
|
||||
|
||||
trait Pet: Animal {
|
||||
fn name(&self) -> String;
|
||||
}
|
||||
|
||||
struct Dog(String);
|
||||
|
||||
impl Animal for Dog {
|
||||
fn leg_count(&self) -> u32 {
|
||||
4
|
||||
}
|
||||
}
|
||||
|
||||
impl Pet for Dog {
|
||||
fn name(&self) -> String {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let puppy = Dog(String::from("Rex"));
|
||||
println!("{} has {} legs", puppy.name(), puppy.leg_count());
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
This is sometimes called "trait inheritance" but students should not expect this
|
||||
to behave like OO inheritance. It just specifies an additional requirement on
|
||||
implementations of a trait.
|
||||
|
||||
<details>
|
Loading…
Reference in New Issue
Block a user