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)
}
}
fn main() {
let d = calculate_distance(Meters(10), Meters(20));
assert_eq!(format!("{}",d), "There are still 30 meters left");
}
/* implement calculate_distance */
fn calculate_distance
```
## Type alias
The most importance of type alias is to improve the readability of our codes.
```rust
type Thunk = Box<dynFn()+Send+'static>;
let f: Thunk = Box::new(|| println!("hi"));
fn takes_long_type(f: Thunk) {
// --snip--
}
fn returns_long_type() -> Thunk {
// --snip--
}
```
```rust
type Result<T> = std::result::Result<T,std::io::Error>;
```
And Unlike newtype, type alias don't create new types, so the following code is valid:
```rust
type Meters = u32;
let x: u32 = 5;
let y: Meters = 5;
println!("x + y = {}", x + y);
```
5γπ
```rust,editable
enum VeryVerboseEnumOfThingsToDoWithNumbers {
Add,
Subtract,
}
/* Fill in the blank */
__
fn main() {
// We can refer to each variant via its alias, not its long and inconvenient
// name.
let x = Operations::Add;
}
```
6γππ There are a few preserved alias in Rust, one of which can be used in `impl` blocks.
```rust,editable
enum VeryVerboseEnumOfThingsToDoWithNumbers {
Add,
Subtract,
}
impl VeryVerboseEnumOfThingsToDoWithNumbers {
fn run(&self, x: i32, y: i32) -> i32 {
match self {
__::Add => x + y,
__::Subtract => x - y,
}
}
}
```
## DST and unsized type
These concepts are complicated, so we are not going to explain here, but you can find them in [The Book](https://doc.rust-lang.org/book/ch19-04-advanced-types.html?highlight=DST#dynamically-sized-types-and-the-sized-trait).
7γπππ Array with dynamic length is a Dynamic Sized Type ( DST ), we can't directly use it
```rust,editable
/* Make it work with const generics */
fn my_function(n: usize) -> [u32; usize] {
[123; n]
}
fn main() {
let arr = my_function();
println!("{:?}",arr);
}
```
8γππ Slice is unsized type, but the reference of slice is not.