Skip to content

Commit

Permalink
WIP II
Browse files Browse the repository at this point in the history
  • Loading branch information
folkertdev committed Sep 19, 2024
1 parent 54cfb07 commit c7131ec
Showing 1 changed file with 76 additions and 10 deletions.
86 changes: 76 additions & 10 deletions slides/2_4-traits-and-generics.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ reverse_slice(&mut ["foo", "bar", "baz"]);
layout: default
---

Similarly, checking membership
# checking membership

```rust
fn slice_contains<T>(haystack: &[T], needle: &T) -> bool {
Expand All @@ -74,7 +74,9 @@ does this work?
layout: default
---

Generic functions must be valid on their own, independent of for which concrete types they are used in practice
# Generic functions must be valid on their own

independent of for which concrete types they are used in practice

```
error[E0369]: binary operation `==` cannot be applied to type `&T`
Expand All @@ -95,6 +97,35 @@ help: consider restricting type parameter `T`
layout: default
---

# restrict a generic by a trait

```rust
fn slice_contains<T: PartialEq>(haystack: &[T], needle: &T) -> bool {
for e in haystack {
if e == needle {
return true;
}
}

false
}

// or

fn slice_contains<T>(haystack: &[T], needle: &T) -> bool
where
T: PartialEq
{
// ...
}
```

---
layout: default
---

# The `PartialEq` trait

```rust
// simplified
pub trait PartialEq {
Expand All @@ -115,7 +146,7 @@ Why `PartialEq`: floats! `NaN` behavior break the laws of `Eq`
layout: default
---

Custom implementations
# Custom trait `impl`s

```rust
enum BookFormat { Paperback, Hardback, Ebook }
Expand Down Expand Up @@ -153,6 +184,8 @@ fn main() {
layout: default
---

# The `PartialEq` trait (for real this time)

```rust
pub trait PartialEq<Rhs = Self>
where
Expand Down Expand Up @@ -180,7 +213,7 @@ impl<'a> PartialEq<String> for &'a str {
layout: default
---

associated types
# Associated types

```rust
pub trait Iterator {
Expand Down Expand Up @@ -221,23 +254,34 @@ loop {
layout: default
---

iterators compose
# Custom iterators

```rust
fn slice_contains<T: PartialEq>(haystack: &[T], needle: &T) -> bool {
haystack.iter().any(|e| e == needle)
struct Range {
start: usize,
end: usize,
}

fn slice_position<T: PartialEq>(haystack: &[T], needle: &T) -> Option<usize> {
haystack.iter().position(|e| e == needle)
impl Iterator for Range {
type Item = usize;

fn next(&mut self) -> Option<Self::Item> {
if self.start < self.end {
let current = self.start;
self.start += 1;
Some(current);
} else {
None
}
}
}
```

---
layout: default
---

How are these different?
# How are these different?

```rust
// std version
Expand Down Expand Up @@ -606,6 +650,28 @@ They just provide information for the borrow checker
layout: default
---

# Notation variations

- the `'_` lifetime can be used to let the compiler infer the lifetime
- two `'_` lifetimes in the same type represent **different** lifetimes

```rust
fn foo(b: &'_ str: , b: &'_ str) {
// a and b have different lifetimes now!
}
```

- the static lifetime lives forever
- string literals and constants have a static lifetime

```rust
let s: &'static str = "hello world";
```

---
layout: default
---

# Validating boundaries

- Lifetime validation is done within function boundaries
Expand Down

0 comments on commit c7131ec

Please sign in to comment.