diff --git a/solutions/generics-traits/generics.md b/solutions/generics-traits/generics.md new file mode 100644 index 0000000..7516660 --- /dev/null +++ b/solutions/generics-traits/generics.md @@ -0,0 +1,88 @@ +1. +```rust +struct A; // Concrete type `A`. +struct S(A); // Concrete type `S`. +struct SGen(T); // Generic type `SGen`. + +fn reg_fn(_s: S) {} + +fn gen_spec_t(_s: SGen) {} + +fn gen_spec_i32(_s: SGen) {} + +fn generic(_s: SGen) {} + +fn main() { + // Using the non-generic functions + reg_fn(S(A)); // Concrete type. + gen_spec_t(SGen(A)); // Implicitly specified type parameter `A`. + gen_spec_i32(SGen(6)); // Implicitly specified type parameter `i32`. + + // Explicitly specified type parameter `char` to `generic()`. + generic::(SGen('a')); + + // Implicitly specified type parameter `char` to `generic()`. + generic(SGen('c')); +} +``` + +2. +```rust +fn sum>(x: T, y: T) -> T { + x + y +} + +fn main() { + assert_eq!(5, sum(2i8, 3i8)); + assert_eq!(50, sum(20, 30)); + assert_eq!(2.46, sum(1.23, 1.23)); +} +``` + + +3. +```rust +struct Point { + x: T, + y: T, +} + +fn main() { + let integer = Point { x: 5, y: 10 }; + let float = Point { x: 1.0, y: 4.0 }; +} +``` + +4. +```rust +// modify this struct to make the code work +struct Point { + x: T, + y: U, +} + +fn main() { + // DON'T modify here + let p = Point{x: 5, y : "hello".to_string()}; +} +``` + +5. +```rust +struct Val { + val: T, +} + +impl Val { + fn value(&self) -> &T { + &self.val + } +} + + +fn main() { + let x = Val{ val: 3.0 }; + let y = Val{ val: "hello".to_string()}; + println!("{}, {}", x.value(), y.value()); +} +``` \ No newline at end of file diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 8fe65eb..a3dd89e 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -22,7 +22,7 @@ - [match, matches! and if let](pattern-match/match-iflet.md) - [Patterns](pattern-match/patterns.md) - [Method & Associated function](method.md) -- [Generics and Traits todo](generics-traits/intro.md) +- [Generics and Traits](generics-traits/intro.md) - [Generics](generics-traits/generics.md) - [Traits](generics-traits/traits.md) - [Trait Object](generics-traits/trait-object.md) diff --git a/src/generics-traits/generics.md b/src/generics-traits/generics.md index 292d26b..2e8f2b0 100644 --- a/src/generics-traits/generics.md +++ b/src/generics-traits/generics.md @@ -1 +1,98 @@ # Generics + +### Functions +1. ๐ŸŒŸ๐ŸŒŸ๐ŸŒŸ +```rust,editable + +// fill in the blanks to make it work +struct A; // Concrete type `A`. +struct S(A); // Concrete type `S`. +struct SGen(T); // Generic type `SGen`. + +fn reg_fn(_s: S) {} + +fn gen_spec_t(_s: SGen) {} + +fn gen_spec_i32(_s: SGen) {} + +fn generic(_s: SGen) {} + +fn main() { + // Using the non-generic functions + reg_fn(__); // Concrete type. + gen_spec_t(__); // Implicitly specified type parameter `A`. + gen_spec_i32(__); // Implicitly specified type parameter `i32`. + + // Explicitly specified type parameter `char` to `generic()`. + generic::(__); + + // Implicitly specified type parameter `char` to `generic()`. + generic(__); +} +``` + +2. ๐ŸŒŸ๐ŸŒŸ A function call with explicitly specified type parameters looks like: `fun::()`. +```rust,editable + +// implement a generic function +fn sum + +fn main() { + assert_eq!(5, sum(2i8, 3i8)); + assert_eq!(50, sum(20, 30)); + assert_eq!(2.46, sum(1.23, 1.23)); +} +``` + + +### Struct and `impl` + +3. ๐ŸŒŸ +```rust,editable + +// implement struct Point to make it work + + +fn main() { + let integer = Point { x: 5, y: 10 }; + let float = Point { x: 1.0, y: 4.0 }; +} +``` + +4. ๐ŸŒŸ๐ŸŒŸ +```rust,editable + +// modify this struct to make the code work +struct Point { + x: T, + y: T, +} + +fn main() { + // DON'T modify here + let p = Point{x: 5, y : "hello".to_string()}; +} +``` + +5. ๐ŸŒŸ๐ŸŒŸ +```rust,editable + +// add generic for Val to make the code work, DON'T modify the code in `main` +struct Val { + val: f64, +} + +impl Val { + fn value(&self) -> &f64 { + &self.val + } +} + + +fn main() { + let x = Val{ val: 3.0 }; + let y = Val{ val: "hello".to_string()}; + println!("{}, {}", x.value(), y.value()); +} +``` +> You can find the solutions [here](https://github.com/sunface/rust-by-practice)(under the solutions path), but only use it when you need it \ No newline at end of file diff --git a/src/generics-traits/intro.md b/src/generics-traits/intro.md index 340ad0e..2af17b0 100644 --- a/src/generics-traits/intro.md +++ b/src/generics-traits/intro.md @@ -1 +1,6 @@ # Generics and Traits +Learning resources: +- English: [Rust Book 10.1, 10.2](https://doc.rust-lang.org/book/ch10-00-generics.html) +- ็ฎ€ไฝ“ไธญๆ–‡: [Rust่ฏญ่จ€ๅœฃ็ป - ๆจกๅผๅŒน้…](https://course.rs/basic/trait/intro.html) + + diff --git a/src/generics-traits/traits.md b/src/generics-traits/traits.md index 445d444..d3d6b44 100644 --- a/src/generics-traits/traits.md +++ b/src/generics-traits/traits.md @@ -1 +1,8 @@ # Traits + + + +fn main() { + assert_eq!(5, sum(2i8, 3u8)); + assert_eq!(50, sum(20, 30.1)); +} \ No newline at end of file diff --git a/src/method.md b/src/method.md index 139162d..6f7d977 100644 --- a/src/method.md +++ b/src/method.md @@ -259,4 +259,7 @@ fn main() { ## Practice -@todo \ No newline at end of file +@todo + + +> You can find the solutions [here](https://github.com/sunface/rust-by-practice)(under the solutions path), but only use it when you need it \ No newline at end of file