30 days of Rust - Day 4
Tags: rust, beginners
Published: 2023-04-26 20:58:41


Dear diary,
Don't blame me for breaking the 6 am rule today - sleep is great at improving your **memory**. I can remember *heaps* of stuff about Rust. How much exactly I can't tell you, as me later at runtime.

## Yesterday's questions answered
- Yes, it's possible to do this once a match has been made. A function could be used to evaluate a second criteria. I can't think of a good example, but this code compiles:
```rust
match n {
	1 if is_greater_than_zero(n) => println!("{} is greater than zero", n),
	0 if is_greater_than_zero(n) => println!("{} is greater than zero", n),
	-1 if is_greater_than_zero(n) => println!("{} is greater than zero", n),
_ => println!("{} unknown number", n),
}
```
- `Some` is a way of evaluating that an `Option` type [is non-null](https://stackoverflow.com/a/36292639/21306705). Typically, retrieving items from collections yields an `Option`.
- `return` is best used to indicate an early exit from a function (in an `if` block, for example). But in essence it's a matter of taste/readability. Opinions [here](https://www.reddit.com/r/rust/comments/v7x8my/when_to_use_return_keyword_in_rust/).
- `impl` isn't doing anything fancy, it's the Rust way of [declaring methods](https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html#:~:text=There%20is%20one%20more%20similarity%20between%20enums%20and%20structs%3A%20just%20as%20we%E2%80%99re%20able%20to%20define%20methods%20on%20structs%20using%20impl%2C%20we%E2%80%99re%20also%20able%20to%20define%20methods%20on%20enums.%20Here%E2%80%99s%20a%20method%20named%20call%20that%20we%20could%20define%20on%20our%20Message%20enum%3A) for a `struct` or `enum`.


## Today's open questions
- What is an `Option` type? (Already answered: An enum that represents the existence (`Some`) or non-existence (`None`) of a variable's value.
- Not really a question but: I was introduced to ownership in the context of scope today, how can I concisely describe this concept?
- Random one: how can I write a unit test in Rust?
- How do I access something on the stack in Rust?
- Why can primitives be reassigned without renouncing ownership?
- Can anything other than a `struct` implement a `trait`?
- What's the difference between an `impl` and `trait`, is `impl` bound to a single `struct`?

## Memories
As the desperate puns at the top suggest, I was introduced to some basics about CS memory management as they relate to Rust.

### Stack it
![stack it](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c4n0vyh7wjoj26jwsapo.jpg)

Anything thing that Rust wants to add to your machine's stack must have a fixed size at compile time. Classic examples of this would be `function`, `struct`, `trait` or `impl`. 

### Rules of the heap
![kinf of the heap](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tot0q79fi4xjxsybmcwb.jpeg)

Your machine's heap contains memory representations of a structure's runtime value. When you add something to the heap, you receive a pointer to its location. Hence why we often access values on the heap using the `&` operator.

Rust implements rules around the heap to provide an opinionated way of managing variables, which also introduces the concept of `ownership`.
1. Each value has a variable that's called its `owner`
2. There is only one owner at a time
3. When the owner goes out of scope the value disappears

### Don't trust your variables (if they ain't primitive)
Whenever you reassign a variable to a new variable, you relieve the former variable of its ownership of the value it points to. If you want to prevent this behaviour, you can call the `clone` method on the value. This only works, however, for non-primative types. Why is that??

This is very different from Python:
```python
my_dict = {"Hello": "World"}
my_final_dict = my_other_dict = my_dict # Valid code by gross!
print(my_final_dict, my_other_dict, my_dict) # No error
```

## More data types
### Hash maps
Not much to say here. Hash maps must have keys and values of the same types, respectively. They have some useful but verbose methods such as `contains_key`. You can count the number of keys using the `len` method and retrieve a key using `get`. `get` will return you an Option which will be either `Some` or `None`.

### Structs
Anyone familiar with JavaScript's `object` or Go's `struct` will know what's up here. Basically, we declare a struct with a number of arbitrarily typed fields. These fields are comma deliniated and wrapped in curly braces.

### Traits
Finally something `::new()`! I learned some basics about `trait` types today. A `trait` can be used in a similar fashion to an `interface` in Go and Java or like a `Protocol` in Python. Combining a `trait` with a `struct` offers a conceptually convenient way to separate data structures from behaviour. Traits also introduced me to the `Self` return type and the `&self` argument.

Different to Go (I think) and Python's `Protocol`, a `trait` must be explicitly `impl`  (slightly less verbosely than Java) for a given `struct`. 


That's it for today -> see you tomorrow.