Skip to content

Commit 67cfbf3

Browse files
authored
Merge pull request #1259 from adamchalmers/supertraits
Fix #90: Add supertraits and Fully Qualified syntax
2 parents fae4db2 + c860ab8 commit 67cfbf3

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed

src/SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@
139139
- [Iterators](trait/iter.md)
140140
- [`impl Trait`](trait/impl_trait.md)
141141
- [Clone](trait/clone.md)
142+
- [Supertraits](traits/supertraits.md)
143+
- [Disambiguating overlapping traits](traits/disambiguating.md)
142144

143145
- [macro_rules!](macros.md)
144146
- [Syntax](macros/syntax.md)

src/traits/disambiguating.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Disambiguating overlapping traits
2+
3+
A type can implement many different traits. What if two traits both require the same name? For example, many traits might have a method named `get()`. They might even have different return types!
4+
5+
Good news: because each trait implementation gets its own `impl` block, it's
6+
clear which trait's `get` method you're implementing.
7+
8+
What about when it comes time to _call_ those methods? To disambiguate between
9+
them, we have to use Fully Qualified Syntax.
10+
11+
```rust,editable
12+
trait UsernameWidget {
13+
// Get the selected username out of this widget
14+
fn get(&self) -> String;
15+
}
16+
17+
trait AgeWidget {
18+
// Get the selected age out of this widget
19+
fn get(&self) -> u8;
20+
}
21+
22+
// A form with both a UsernameWidget and an AgeWidget
23+
struct Form {
24+
username: String,
25+
age: u8,
26+
}
27+
28+
impl UsernameWidget for Form {
29+
fn get(&self) -> String {
30+
self.username.clone()
31+
}
32+
}
33+
34+
impl AgeWidget for Form {
35+
fn get(&self) -> u8 {
36+
self.age
37+
}
38+
}
39+
40+
fn main() {
41+
let form = Form{
42+
username: "rustacean".to_owned(),
43+
age: 28,
44+
};
45+
46+
// If you uncomment this line, you'll get an error saying
47+
// "multiple `get` found". Because, after all, there are multiple methods
48+
// named `get`.
49+
// println!("{}", form.get());
50+
51+
let username = <Form as UsernameWidget>::get(&form);
52+
assert_eq!("rustacean".to_owned(), username);
53+
let age = <Form as AgeWidget>::get(&form);
54+
assert_eq!(28, age);
55+
}
56+
```
57+
58+
### See also:
59+
60+
[The Rust Programming Language chapter on Fully Qualified syntax][trpl_fqsyntax]
61+
62+
[trpl_fqsyntax]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name

src/traits/supertraits.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Supertraits
2+
3+
Rust doesn't have "inheritance", but you can define a trait as being a superset
4+
of another trait. For example:
5+
6+
```rust,editable
7+
trait Person {
8+
fn name(&self) -> String;
9+
}
10+
11+
// Student is a supertrait of Person.
12+
// Implementing Student requires you to also impl Person.
13+
trait Student: Person {
14+
fn university(&self) -> String;
15+
}
16+
17+
trait Programmer {
18+
fn fav_language(&self) -> String;
19+
}
20+
21+
// CompSciStudent (computer science student) is a supertrait of both Programmer
22+
// and Student. Implementing CompSciStudent requires you to impl both subtraits.
23+
trait CompSciStudent: Programmer + Student {
24+
fn git_username(&self) -> String;
25+
}
26+
27+
fn comp_sci_student_greeting(student: &dyn CompSciStudent) -> String {
28+
format!(
29+
"My name is {} and I attend {}. My Git username is {}",
30+
student.name(),
31+
student.university(),
32+
student.git_username()
33+
)
34+
}
35+
36+
fn main() {}
37+
```
38+
39+
### See also:
40+
41+
[The Rust Programming Language chapter on supertraits][trpl_supertraits]
42+
43+
[trpl_supertraits]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#using-supertraits-to-require-one-traits-functionality-within-another-trait

0 commit comments

Comments
 (0)