rust-by-practice/solutions/newtype-sized.md

171 lines
2.7 KiB
Markdown
Raw Permalink Normal View History

2022-11-06 22:06:19 -06:00
1.
2022-05-01 00:08:50 -05:00
2022-03-31 06:52:57 -06:00
```rust
use std::fmt;
struct Wrapper(Vec<String>);
impl fmt::Display for Wrapper {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}]", self.0.join(", "))
}
}
fn main() {
let w = Wrapper(vec![String::from("hello"), String::from("world")]);
println!("w = {}", w);
}
```
2022-11-06 22:06:19 -06:00
2.
2022-05-01 00:08:50 -05:00
2022-03-31 06:52:57 -06:00
```rust
struct Meters(u32);
fn main() {
let i: u32 = 2;
assert_eq!(i.pow(2), 4);
let n = Meters(i);
assert_eq!(n.0.pow(2), 4);
}
```
2022-11-06 22:06:19 -06:00
3.
2022-05-01 00:08:50 -05:00
2022-03-31 06:52:57 -06:00
```rust
struct Years(i64);
struct Days(i64);
impl Years {
pub fn to_days(&self) -> Days {
Days(self.0 * 365)
}
}
impl Days {
pub fn to_years(&self) -> Years {
Years(self.0 / 365)
}
}
// an age verification function that checks age in years, must be given a value of type Years.
fn old_enough(age: &Years) -> bool {
age.0 >= 18
}
fn main() {
let age = Years(5);
let age_days = age.to_days();
println!("Old enough {}", old_enough(&age));
println!("Old enough {}", old_enough(&age_days.to_years()));
}
```
2022-11-06 22:06:19 -06:00
4. Sometimes `newtype` pattern can provide extra readability.
2022-05-01 00:08:50 -05:00
2022-03-31 06:52:57 -06:00
```rust
use std::ops::Add;
use std::fmt::{self, format};
struct Meters(u32);
2022-05-01 00:08:50 -05:00
2022-03-31 06:52:57 -06:00
impl fmt::Display for Meters {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "There are still {} meters left", self.0)
}
}
impl Add for Meters {
type Output = Self;
fn add(self, other: Meters) -> Self {
Self(self.0 + other.0)
}
}
2022-05-01 00:08:50 -05:00
2022-03-31 06:52:57 -06:00
fn main() {
let d = calculate_distance(Meters(10), Meters(20));
2022-05-01 00:08:50 -05:00
assert_eq!(format!("{}", d), "There are still 30 meters left");
2022-03-31 06:52:57 -06:00
}
/* implement calculate_distance */
fn calculate_distance(d1: Meters, d2: Meters) -> Meters {
d1 + d2
}
```
2022-11-06 22:06:19 -06:00
5.
2022-05-01 00:08:50 -05:00
2022-03-31 06:52:57 -06:00
```rust
enum VeryVerboseEnumOfThingsToDoWithNumbers {
Add,
Subtract,
}
/* Fill in the blank */
type Operations = VeryVerboseEnumOfThingsToDoWithNumbers;
fn main() {
// We can refer to each variant via its alias, not its long and inconvenient
// name.
let x = Operations::Add;
}
```
2022-11-06 22:06:19 -06:00
6.
2022-05-01 00:08:50 -05:00
2022-03-31 06:52:57 -06:00
```rust
enum VeryVerboseEnumOfThingsToDoWithNumbers {
Add,
Subtract,
}
impl VeryVerboseEnumOfThingsToDoWithNumbers {
fn run(&self, x: i32, y: i32) -> i32 {
match self {
Self::Add => x + y,
Self::Subtract => x - y,
}
}
}
2022-05-01 00:08:50 -05:00
fn main() {}
2022-03-31 06:52:57 -06:00
```
2022-11-06 22:06:19 -06:00
7.
2022-05-01 00:08:50 -05:00
2022-03-31 06:52:57 -06:00
```rust
fn my_function<const N: usize>() -> [u32; N] {
[123; N]
}
fn main() {
let arr = my_function::<5>();
2022-05-01 00:08:50 -05:00
println!("{:?}", arr);
2022-03-31 06:52:57 -06:00
}
```
2022-11-06 22:06:19 -06:00
8.
2022-05-01 00:08:50 -05:00
2022-03-31 06:52:57 -06:00
```rust
fn main() {
let s: &str = "Hello there!";
let arr: &[u8] = &[1, 2, 3];
}
```
2022-11-06 22:06:19 -06:00
9.
2022-05-01 00:08:50 -05:00
2022-03-31 06:52:57 -06:00
```rust
use std::fmt::Display;
2022-05-01 00:08:50 -05:00
fn foobar_1(thing: &dyn Display) {}
fn foobar_2(thing: Box<dyn Display>) {}
fn main() {}
2022-03-31 06:52:57 -06:00
```