Last active
March 7, 2023 17:37
-
-
Save exlee/2f4d3fbf3e3c4a80878ea963c1c8dc8a to your computer and use it in GitHub Desktop.
Rust: Why we don't alias mutable references.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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