{
pin1: &'static P,
pin2: &'static P,
// ...
}
```
And without trait bounds
```rust
struct MyDriver {
pin1: &'static P,
pin2: &'static P,
// ...
}
```
---
## Generic Types With Trait Bounds
```rust
impl Driver for MyDriver {
// ...
}
```
---
## Inheritance (kinda)
- Some traits may require other traits to be implemented first.
- e.g., `Eq` requires that `PartialEq` be implemented, and `Copy` requires `Clone`.
- Implementing the `Child` trait below requires you to also implement `Parent`.
```rust
trait Parent {
fn foo(&self) {
// ...
}
}
trait Child: Parent {
fn bar(&self) {
self.foo();
// ...
}
}
```
---
# Lifetimes Annotations
- Lifetimes generally have a pretty steep learning curve.
- Don't worry if you don't understand these right away.
.title[.center[]]
---
### Question .top_image[]
Q1: How do you use free?
```c
#include
#include
#include
char * without_first_word (char *s);
int main ()
{
char * s = strdup ("ana has apples");
char *wfw = without_first_word (s);
// free (s); <-- before printf // possible?
printf ("%s\n", wfw);
// free (wfw); <-- after printf // possible?
}
```
---
### Question .top_image[]
Q2: How do you use free?
```c
// program: bear-salamander-anteater
#include
#include
#include
char * without_first_word (char *s) {
int pos = 0;
for (unsigned int i=0; i < strlen (s); i++) {
if (s[i] != ' ') pos = pos + 1;
else break;
}
return &s[pos];
}
int main ()
{
char * s = strdup ("ana has apples");
char *wfw = without_first_word (s);
// free (s); <-- before printf // possible?
printf ("%s\n", wfw);
// free (wfw); <-- after printf // possible?
}
```
---
### Question .top_image[]
Q3: How do you use free?
```c
// program: oyster-guanaco-dinosaur
#include
#include
#include
char * without_first_word (char *s) {
int pos = 0;
for (unsigned int i=0; i < strlen (s); i++) {
if (s[i] != ' ') pos = pos + 1;
else break;
}
return strdup (&s[pos]);
}
int main ()
{
char * s = strdup ("ana has apples");
char *wfw = without_first_word (s);
// free (s); <-- before printf / possible?
printf ("%s\n", wfw);
// free (wfw); <-- before printf / possible?
}
```
---
### Lifetime annotations
From a birds eye view, how should Rust free `s` and `wfw`?
```rust
fn without_first_word<'a> (s: &'a str) -> &'a str;
fn main() {
let s = String::from("ana has apples");
let wfw = without_first_word (&s);
// drop(s); // Is this possible?
println! ("{}", wfw);
// drop(s); // Is this possible?
}
```
---
### This is why lifetimes are useful.
```rust
fn without_first_word<'a> (s: &'a str) -> &'a str {
let mut pos = 0;
for a in s.chars() {
if a != ' ' { pos = pos + 1; }
else { break; }
}
&s[pos..]
}
fn main() {
let s = String::from("ana has apples");
let wfw = without_first_word (&s);
// drop(s); // possible?
println! ("{}", wfw);
}
```
---
### Lifetime annotations
```rust
fn without_first_word(_s: &str) -> &str {
todo!()
}
fn main() {
let s = String::from("ana has apples");
let wfw = without_first_word (&s);
drop(s); // possible?
println! ("{}", wfw);
}
```
---
### Question .top_image[]
Can we use free for `s1` and `s2` before `printf`?
```c
#include
#include
#include
char * smaller (char *s1, char *s2);
int main () {
char *s1 = strdup ("ip");
char *s2 = strdup ("workshop");
char *small = smaller (s1, s2);
// free (s1); // possible?
// free (s2); // possible?
printf ("%s\n", small);
}
```
---
### Multiple Lifetime Parameters
```c
// program: wolverine-mallard-gull
#include
#include
#include
char * smaller (char *s1, char *s2) {
if (strlen(s1) > strlen(s2)) return s2;
else return s1;
}
int main () {
char *s1 = strdup ("ip");
char *s2 = strdup ("workshop");
char *small = smaller (s1, s2);
// free (s1); // possible?
// free (s2); // possible?
printf ("%s\n", small);
}
```
---
### Multiple Lifetime Parameters
```rust
fn smaller <'a> (s1: &'a str, s2: &'a str) -> &'a str {}
fn main() {
let s1 = String::from("ip");
let s2 = String::from("workshop");
let small = smaller (&s1, &s2);
// drop(s1); // possible?
// drop(s2); // possible?
println! ("{}", small);
}
```
---
### Question .top_image[]
Why can't we free s2?
```rust
fn append <'a> (s: &'a mut String, n: &'a str) -> &'a str {
s.push_str (n);
s
}
fn main() {
let mut s1 = String::from("ip");
let s2 = String::from(" workshop");
let title = append (&mut s1, &s2);
drop(s2); // possible?
println! ("{}", title);
}
```
---
### Multiple Lifetime Parameters
We now can free s2.
```rust
fn append <'a, 'b> (s: &'a mut String, n: &'b str) -> &'a str {
s.push_str (n);
s
}
fn main() {
let mut s1 = String::from("ip");
let s2 = String::from(" workshop");
let title = append (&mut s1, &s2);
drop(s2); // possible?
println! ("{}", title);
}
```
---
# Take a break, and check these out when you can
- Rustlings (https://rustlings.rust-lang.org/)
- PM Rust Part 1 (https://embedded-rust-101.wyliodrin.com/docs/fils_en/lab/00.0)
- PM Rust Part 2 (https://embedded-rust-101.wyliodrin.com/docs/fils_en/lab/00.1)