Skip to content

Instantly share code, notes, and snippets.

@exlee
Last active March 7, 2023 17:37
Show Gist options
  • Save exlee/2f4d3fbf3e3c4a80878ea963c1c8dc8a to your computer and use it in GitHub Desktop.
Save exlee/2f4d3fbf3e3c4a80878ea963c1c8dc8a to your computer and use it in GitHub Desktop.
Rust: Why we don't alias mutable references.
// Person here is shallow on many levels
struct Person { name: String, attractiveness: u8 }
impl Person {
fn glance(&self, someone: &Person) {
let look = match(someone.attractiveness) {
0 ..= 2 => "...uuhh..",
3 ..= 5 => "good. Definitelly good!",
6 ..= 8 => "great!",
9 ..= 10 => "amazing!!",
11 | _ => {
println!("*GASP*");
return
}
};
println!("{}, you look {}", someone.name, look)
}
}
type Bride = Person;
type Groom = Person;
// Simple macro that doesn't run (nor compile) its innards
macro_rules! HOLD_UP { ($e:stmt) => {} }
// This room has a lifetime. Nice one, not cryptic a's or b's .
// Simply - room cannot collapse while soemeone's in it
struct PreparationRoom<'person_exists> {
seat: Option<&'person_exists mut Person>
}
impl<'p> PreparationRoom<'p> { // 'p == 'person_exists -- I'm a lazy typer
fn new() -> Self { Self { seat: None }}
// Sure, we could take ownership, but we're not Jail!
fn seat(&mut self, someone: &'p mut Person) {
self.seat = Some(someone);
}
fn commence(&mut self) {
// ...some things are better left untold...
self.seat.as_mut().unwrap().attractiveness = 2;
}
fn finish_preparations(&mut self) {
// It gets EVEN BETTER!
self.seat.as_mut().unwrap().attractiveness = 11;
self.seat = None
}
}
fn wedding_preparations() {
// Our stage
let mut preparation_room = PreparationRoom::new();
// .. and a beautiful couple!
let mut john = Groom { name: String::from("John"), attractiveness: 10 };
let mut jill = Bride { name: String::from("Jill"), attractiveness: 10 };
// Bye, Jill!
preparation_room.seat(&mut jill);
preparation_room.commence();
// Sheesh, John! Don't do that!
HOLD_UP! {
john.glance(&jill)
}
// ...everyone knows that catching bride during preparation is against
// Rust's rule about aliasing mutable references!
// Also. Believe me. You aren't ready...
preparation_room.finish_preparations();
john.glance(&jill);
}
fn main() { wedding_preparations() }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment