Skip to content

Commit

Permalink
Merge pull request #89 from ferrous-systems/amanjeev/some-notes
Browse files Browse the repository at this point in the history
Some notes from last few trainings
  • Loading branch information
amanjeev committed Aug 21, 2023
2 parents 80c7a16 + 63480ad commit 05cc19b
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 47 deletions.
4 changes: 4 additions & 0 deletions training-slides/src/basic-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,7 @@ fn main() {
let sub: &[i32] = &slice[0..1];
}
```

Note:

- Use `.get()` method on the slice to avoid panics instead of accessing via index.
20 changes: 10 additions & 10 deletions training-slides/src/collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,16 +380,16 @@ Just sets the `V` type parameter to `()`!

## A Summary

| Type | Owns | Grow | Index | Slice | Cheap Insert |
| ------------ | :---: | :---: | :-----: | :---: | :----------: |
| Array | | | `usize` | | |
| Slice | | | `usize` | | |
| Vec | | | `usize` | ||
| String Slice | | | 🤔 | | |
| String | | | 🤔 | ||
| VecDeque | | | `usize` | 🤔 | ↪ / ↩ |
| HashMap | | | `T` | | |
| BTreeMap | | | `T` | | |
| Type | Owns | Grow | Index | Slice | Cheap Insert |
| :----------- | :--: | :--: | :-----: | :---: | :----------: |
| Array ||| `usize` |||
| Slice ||| `usize` |||
| Vec ||| `usize` |||
| String Slice ||| 🤔 |||
| String ||| 🤔 |||
| VecDeque ||| `usize` | 🤔 | ↪ / ↩ |
| HashMap ||| `T` |||
| BTreeMap ||| `T` |||

Note:

Expand Down
62 changes: 40 additions & 22 deletions training-slides/src/compound-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,51 +17,59 @@ struct Point {

- there is no partial initialization

```rust [1-4|6]
```rust [1-4|6-8]
struct Point {
x: i32,
y: i32,
}

let p = Point { x: 1, y: 2 };
fn main() {
let p = Point { x: 1, y: 2 };
}
```

## Construction

- but you can copy from an existing variable of the same type

```rust [7]
```rust [8]
struct Point {
x: i32,
y: i32,
}

let p = Point { x: 1, y: 2 };
let q = Point { x: 4, ..p };
fn main() {
let p = Point { x: 1, y: 2 };
let q = Point { x: 4, ..p };
}
```

## Field Access

```rust [1-4|6|7-8]
```rust [1-4|7|8-9]
struct Point {
x: i32,
y: i32,
}

let p = Point { x: 1, y: 2 };
println!("{}", p.x);
println!("{}", p.y);
fn main() {
let p = Point { x: 1, y: 2 };
println!("{}", p.x);
println!("{}", p.y);
}
```

## Tuples

- Holds values of different types together.
- Like an anonymous `struct`, with fields numbered 0, 1, etc.

```rust [1|2-3]
let p = (1, 2);
println!("{}", p.0);
println!("{}", p.1);
```rust [2|3-4]
fn main() {
let p = (1, 2);
println!("{}", p.0);
println!("{}", p.1);
}
```

## `()`
Expand All @@ -80,12 +88,14 @@ fn prints_but_returns_nothing(data: &str) -> () {

- Like a `struct`, with fields numbered 0, 1, etc.

```rust [1|3|4-5]
```rust [1|4|5-6]
struct Point(i32,i32);

let p = Point(1, 2);
println!("{}", p.0);
println!("{}", p.1);
fn main() {
let p = Point(1, 2);
println!("{}", p.0);
println!("{}", p.1);
}
```

## Enums
Expand All @@ -102,29 +112,33 @@ println!("{}", p.1);

## enum: Definition and Construction

```rust [1-6|8]
```rust [1-6|9]
enum Shape {
Square,
Circle,
Rectangle,
Triangle,
}

let shape = Shape::Rectangle;
fn main() {
let shape = Shape::Rectangle;
}
```

## Enums with Values

```rust [1-6|2-4|5|8|9]
```rust [1-6|2-4|5|9|10]
enum Movement {
Right(i32),
Left(i32),
Up(i32),
Down { speed: i32, excitement: u8 },
}

let movement = Movement::Left(12);
let movement = Movement::Down { speed: 12, excitement: 5 };
fn main() {
let movement = Movement::Left(12);
let movement = Movement::Down { speed: 12, excitement: 5 };
}
```

## Enums with Values
Expand Down Expand Up @@ -201,6 +215,10 @@ fn check_shape(shape: &Shape) {
}
```

Note:

You might ask "Why is there a `*` in front of `radius` in `match`?" - It's because you only have an `&Shape` and so if you pattern match on a value of that type, you can only get a `&` reference to its contents. Unfortunately, the Rust operator `>` (or rather, the trait `std::cmp::PartialOrd` is implemented to compare two `i32` values, but not to compare an `i32` with an `&i32`.

## Combining patterns

- You can use the `|` operator to join patterns together
Expand Down
7 changes: 7 additions & 0 deletions training-slides/src/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ You can put anything in for the `E` in `Result<T, E>`:
fn literals() -> Result<(), &'static str> {
Err("oh no")
}

fn strings() -> Result<(), String> {
Err(String::from("oh no"))
}

fn enums() -> Result<(), Error> {
Err(Error::BadThing)
}
Expand Down Expand Up @@ -191,3 +193,8 @@ fn main() -> Result<(), anyhow::Error> {
Ok(())
}
```

Note:

* Use `anyhow` if you do not care what error type your function returns, just that it captures something.
* Use `thiserror` if you must design your own error types but want easy `Error` trait impl.
8 changes: 8 additions & 0 deletions training-slides/src/generics.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ fn print_stuff<X>(value: X) {
}
```

Note:

Default bounds are `Sized`, so finding the size of the type is one thing that you can do. You can also take a reference or a pointer to the value.

## Generic Implementations

```rust []
Expand Down Expand Up @@ -228,6 +232,10 @@ impl AreaCalculator {
}
```

Note:

Some types that cannot be written out, like the closure, can be expressed as return types using `impl`. e.g. `fn score(y: i32) -> impl Fn(i32) -> i32`.

## Caution

* Using Generics is *Hard Mode Rust*
Expand Down
24 changes: 14 additions & 10 deletions training-slides/src/good-design-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ mod tests {
```rust ignore
struct Point(i32, i32);

let p = Point (1, 2);
assert_eq!(p, Point(1, 2));
fn main() {
let p = Point (1, 2);
assert_eq!(p, Point(1, 2));
}
```

Errors:
Expand All @@ -80,8 +82,10 @@ Errors:
#[derive(Debug, PartialEq)]
struct Point(i32, i32);

let p = Point (1, 2);
assert_eq!(p, Point(1, 2));
fn main() {
let p = Point (1, 2);
assert_eq!(p, Point(1, 2));
}
```

## `Debug`
Expand All @@ -95,12 +99,12 @@ struct Point { x: i32, y: i32 }
#[derive(Debug)]
struct TuplePoint(i32, i32);

let p = Point { y: 2, x: 1 };
let tp = TuplePoint (1, 2);
println!("{:?}", p);
// Point { x: 1, y: 2 }
println!("{:?}", tp);
// TuplePoint (1, 2)
fn main() {
let p = Point { y: 2, x: 1 };
let tp = TuplePoint (1, 2);
println!("{:?}", p); // Point { x: 1, y: 2 }
println!("{:?}", tp); // TuplePoint (1, 2)
}
```

## `PartialEq`
Expand Down
17 changes: 14 additions & 3 deletions training-slides/src/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,18 @@ Rust is an empathic systems programming language that is determined to not let y
## Release Method

- Nightly releases

- experimental features are only present on nighly releases
- Every 6 weeks, the current nightly is promoted to beta
- After 6 weeks of testing, beta becomes stable
- Guaranteed backwards-compatibility
- Makes small iterations easier

Note:

- Cargo's "stabilization" section https://doc.crates.io/contrib/process/unstable.html#stabilization
- Crater tool
- Editions

## Goals

- Explicit over implicit
Expand All @@ -75,13 +80,19 @@ spend time discussing the impact of many features on large projects.
- Deallocation is automated
- Warning: memory leaks are **safe** by that definition!

Note:

- Memory safety: use-after-free, double-free
- Type safety, Thread safety
- Memory leaks: `Box::leak()`

## Concurrent

- "Concurrency without fear"
- The type system detects concurrent access to data and requires
synchronisation
- Also: Rust detects when unsynchronised access is safely possible!
- Protection from data races!
- Also: Rust detects when unsynchronised access is safely possible
- Protection from data races

## Fast

Expand Down
8 changes: 6 additions & 2 deletions training-slides/src/ownership.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Ownership is the basis for the memory management of Rust.
- The owner is responsible for removing the data from memory
- The owner always has full control over the data and can mutate it

## These Rules are:
## These Rules are

- fundamental to Rust’s type system
- enforced at compile time
Expand All @@ -33,7 +33,7 @@ fn print_string(s: String) {

Note:

The statement `let s = ...;` introduces a *variable binding* called `f` and gives it a *value* which is of type `String`. This distinction is important when it comes to transferring ownership.
The statement `let s = ...;` introduces a *variable binding* called `s` and gives it a *value* which is of type `String`. This distinction is important when it comes to transferring ownership.

The function `String::from` is an associated function called `from` on the `String` type.

Expand Down Expand Up @@ -212,6 +212,10 @@ Try adding more excitement by calling `add_excitement` multiple times.
* *Mutably Borrowing* gives more permissions than *Borrowing*
* *Owning* gives more permissions than *Mutably Borrowing*

Note:

Why are there two types of Borrowed string types (`&String` and `&str`)? The first is a reference to a `struct` (`std::string::String`, specifically), and the latter is a built-in slice type which points at some bytes in memory which are valid UTF-8 encoded characters.

## An aside: Method Calls

* Rust supports *Method Calls*
Expand Down

0 comments on commit 05cc19b

Please sign in to comment.