233 lines
4.7 KiB
Markdown
233 lines
4.7 KiB
Markdown
1.
|
|
|
|
```rust
|
|
struct Container(i32, i32);
|
|
|
|
// A trait which checks if 2 items are stored inside of container.
|
|
// Also retrieves first or last value.
|
|
trait Contains {
|
|
// Define generic types here which methods will be able to utilize.
|
|
type A;
|
|
type B;
|
|
|
|
fn contains(&self, _: &Self::A, _: &Self::B) -> bool;
|
|
fn first(&self) -> i32;
|
|
fn last(&self) -> i32;
|
|
}
|
|
|
|
impl Contains for Container {
|
|
// Specify what types `A` and `B` are. If the `input` type
|
|
// is `Container(i32, i32)`, the `output` types are determined
|
|
// as `i32` and `i32`.
|
|
type A = i32;
|
|
type B = i32;
|
|
|
|
// `&Self::A` and `&Self::B` are also valid here.
|
|
fn contains(&self, number_1: &i32, number_2: &i32) -> bool {
|
|
(&self.0 == number_1) && (&self.1 == number_2)
|
|
}
|
|
// Grab the first number.
|
|
fn first(&self) -> i32 { self.0 }
|
|
|
|
// Grab the last number.
|
|
fn last(&self) -> i32 { self.1 }
|
|
}
|
|
|
|
fn difference<C: Contains>(container: &C) -> i32 {
|
|
container.last() - container.first()
|
|
}
|
|
|
|
fn main() {
|
|
let number_1 = 3;
|
|
let number_2 = 10;
|
|
|
|
let container = Container(number_1, number_2);
|
|
|
|
println!("Does container contain {} and {}: {}",
|
|
&number_1, &number_2,
|
|
container.contains(&number_1, &number_2));
|
|
println!("First number: {}", container.first());
|
|
println!("Last number: {}", container.last());
|
|
|
|
println!("The difference is: {}", difference(&container));
|
|
}
|
|
```
|
|
|
|
2.
|
|
|
|
```rust
|
|
impl<T: Sub<Output = T>> Sub<Point<T>> for Point<T> {
|
|
type Output = Self;
|
|
|
|
fn sub(self, other: Self) -> Self::Output {
|
|
Point {
|
|
x: self.x - other.x,
|
|
y: self.y - other.y,
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
```rust
|
|
impl<T: Sub<Output = T>> Sub<Self> for Point<T> {
|
|
type Output = Self;
|
|
|
|
fn sub(self, other: Self) -> Self::Output {
|
|
Point {
|
|
x: self.x - other.x,
|
|
y: self.y - other.y,
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
```rust
|
|
impl<T: Sub<Output = T>> Sub for Point<T> {
|
|
type Output = Self;
|
|
|
|
fn sub(self, other: Self) -> Self::Output {
|
|
Point {
|
|
x: self.x - other.x,
|
|
y: self.y - other.y,
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
3.
|
|
|
|
```rust
|
|
trait Pilot {
|
|
fn fly(&self) -> String;
|
|
}
|
|
|
|
trait Wizard {
|
|
fn fly(&self) -> String;
|
|
}
|
|
|
|
struct Human;
|
|
|
|
impl Pilot for Human {
|
|
fn fly(&self) -> String {
|
|
String::from("This is your captain speaking.")
|
|
}
|
|
}
|
|
|
|
impl Wizard for Human {
|
|
fn fly(&self) -> String {
|
|
String::from("Up!")
|
|
}
|
|
}
|
|
|
|
impl Human {
|
|
fn fly(&self) -> String {
|
|
String::from("*waving arms furiously*")
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let person = Human;
|
|
assert_eq!(Pilot::fly(&person), "This is your captain speaking.");
|
|
assert_eq!(Wizard::fly(&person), "Up!");
|
|
|
|
assert_eq!(person.fly(), "*waving arms furiously*");
|
|
|
|
println!("Success!")
|
|
}
|
|
```
|
|
|
|
4.
|
|
|
|
```rust
|
|
trait Person {
|
|
fn name(&self) -> String;
|
|
}
|
|
|
|
// Person is a supertrait of Student.
|
|
// Implementing Student requires you to also impl Person.
|
|
trait Student: Person {
|
|
fn university(&self) -> String;
|
|
}
|
|
|
|
trait Programmer {
|
|
fn fav_language(&self) -> String;
|
|
}
|
|
|
|
// CompSciStudent (computer science student) is a subtrait of both Programmer
|
|
// and Student. Implementing CompSciStudent requires you to impl both supertraits.
|
|
trait CompSciStudent: Programmer + Student {
|
|
fn git_username(&self) -> String;
|
|
}
|
|
|
|
fn comp_sci_student_greeting(student: &dyn CompSciStudent) -> String {
|
|
format!(
|
|
"My name is {} and I attend {}. My favorite language is {}. My Git username is {}",
|
|
student.name(),
|
|
student.university(),
|
|
student.fav_language(),
|
|
student.git_username()
|
|
)
|
|
}
|
|
|
|
struct CSStudent {
|
|
name: String,
|
|
university: String,
|
|
fav_language: String,
|
|
git_username: String
|
|
}
|
|
|
|
impl Person for CSStudent {
|
|
fn name(&self) -> String {
|
|
self.name.clone()
|
|
}
|
|
}
|
|
|
|
impl Student for CSStudent {
|
|
fn university(&self) -> String {
|
|
self.university.clone()
|
|
}
|
|
}
|
|
|
|
impl Programmer for CSStudent {
|
|
fn fav_language(&self) -> String {
|
|
self.fav_language.clone()
|
|
}
|
|
}
|
|
|
|
impl CompSciStudent for CSStudent {
|
|
fn git_username(&self) -> String {
|
|
self.git_username.clone()
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let student = CSStudent {
|
|
name: "Sunfei".to_string(),
|
|
university: "XXX".to_string(),
|
|
fav_language: "Rust".to_string(),
|
|
git_username: "sunface".to_string()
|
|
};
|
|
|
|
println!("{}", comp_sci_student_greeting(&student));
|
|
}
|
|
```
|
|
|
|
5.
|
|
|
|
```rust
|
|
use std::fmt;
|
|
|
|
// DEFINE a newtype `Pretty`
|
|
struct Pretty(String);
|
|
|
|
impl fmt::Display for Pretty {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
write!(f, "\"{}\"", self.0.clone() + ", world")
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let w = Pretty("hello".to_string());
|
|
println!("w = {}", w);
|
|
}
|
|
``` |