Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Cost of Ownership: Should You Rent or Buy?

The Cost of Ownership: Should You Rent or Buy?

My January Columbus Rust Society presentation on Rust's Ownership system.

Alex Burkhart

January 28, 2015
Tweet

More Decks by Alex Burkhart

Other Decks in Technology

Transcript

  1. "The goal is to design and implement a safe, concurrent,

    practical, static systems language." — Rust Project FAQ
  2. Strings fn greet(name: String) { println!("Hello {:?}!", name); } fn

    main() { let person = "Alex"; greet(person); }
  3. Two String Types fn greet(name: String) { println!("Hello {:?}!", name);

    } fn main() { let person: &str = "Alex"; greet(person); }
  4. Use the Right String fn greet(name: String) { println!("Hello {:?}!",

    name); } fn main() { let person: String = "Alex".to_string(); greet(person); }
  5. String Slices fn greet(name: &str) { println!("Hello {:?}!", name); }

    fn main() { let person: &str = "Alex"; greet(person); }
  6. Stack & Heap Memory #[derive(Debug)] enum Color { Red, Yellow,

    Green, } fn main() { let stack: Color = Color::Red; let heap: Box<Color> = box Color::Green; println!("stack: {:?}, heap: {:?}", stack, heap); }
  7. Stack & Heap Memory fn main() { let stack: Color

    = Color::Red; let heap: Box<Color> = box Color::Green; // C: int *ptr = malloc(sizeof(Color)); println!("stack: {:?}, heap: {:?}", stack, heap); // end of scope, memory gets freed // C: free(heap); }
  8. Ownership fn main() { let r = box Color::Red; //

    allocate some memory println!("the value of r: {:?}", r); // access r let color = r; // transfer ownership to `color` println!("the value of color: {:?}", color); // access color println!("the value of color: {:?}", r); // => error: use of moved value: `r` // owner `color` falls out of scope // implicit drop(owner); }
  9. Borrowing fn main() { let r: Box<Color> = box Color::Red;

    // allocate some memory println!("the value of r: {:?}", r); // access r let color: &Box<Color> = &r; // borrow a reference // access borrowed value println!("the value of color: {:?}", color); // access owned value println!("the value of color: {:?}", r); // borrower & owner are both dropped }
  10. Borrow Checker fn main() { let x = box 2014u32;

    { // introduce new scope let y = &x; println!("x: {:?}, y: {:?}", x, y); } // y is dropped println!("{:?}", x); } // x is dropped
  11. Strings Revisited fn greet(name: &str) { println!("Hello {:?}!", name); }

    fn main() { let person: &'static str = "Alex"; greet(person); }
  12. Why Ownership? fn main() { let x: Vec<Color> = vec![Color::Red,

    Color::Green, Color::Red]; // if we shallow copied... let y = x; // x frees its vector contents // y frees the *same* vector contents // double free! SEGFAULT }
  13. Ownership Saves the Day fn main() { let x: Vec<Color>

    = vec![Color::Red, Color::Green, Color::Red]; // the ownership of the vec *moves* to y let y = x; println!("{:?}", y); // => ok, y owns it println!("{:?}", x); // => error! use of moved value // x is already invalidated // y frees the vector contents }
  14. Movement & Borrowing fn main() { let x = box

    Color::Green; // x is the owner of memory let y = &x; // y borrows x // everyone can read immutably borrowed memory! println!("{:?}", x); // ok! println!("{:?}", y); // ok! let k = x; // => error: cannot move out of `x` because it is borrowed }
  15. Moving Copying Borrowed References fn main() { let x =

    box Color::Green; // x is the owner of memory let y = &x; // y borrows x // everyone can read immutably borrowed memory! println!("{:?}", x); // ok! println!("{:?}", y); // ok! // *copy* the reference to the Box let k = y; println!("{:?}", k); // ok! println!("{:?}", y); // ok! }
  16. When does it Move? enum Foo { F1, F2 }

    impl Copy for Foo {} enum Bar { B1, B2 } // !Copy fn main() { let f = Foo::F1 let g = f; // copied let b = Bar::B1; let c = b; // moved }
  17. Ownership Returning Functions fn fresh_pot() -> Coffee { Coffee::Hot(212) }

    fn main() { let cup = box fresh_pot(); drink_coffee(cup); } fn dangling_pointer() -> &Coffee { let failure = Coffee::Instant; &failure }
  18. Ownership Taking Functions fn drink_coffee(owned: Box<Coffee>) { if is_acceptable(&*owned) {

    println!("Bliss..."); } else { println!("This is unacceptable!"); } } fn is_acceptable(borrowed: &Coffee) -> bool { match *borrowed { Coffee::Iced(x) if x => true, Coffee::Hot(temp) if temp > 140 => true, _ => false, } }
  19. Slices Revisited fn main() { let vector: Vec<u32> = vec![1,

    2, 3]; let v_slice: &[u32] = vector.as_slice(); println!("{:?} and {:?} are the same *exact* data!", vector, v_slice); }
  20. Threads use std::sync::mpsc::channel; use std::thread::Thread; fn main() { let (tx,

    rx) = channel(); Thread::spawn(move || { tx.send("Data produced in child task").unwrap(); }).detach(); let data = rx.recv().unwrap(); println!("{:?}", data); // 1x => Data produced in child task }
  21. Multiple Threads use std::sync::mpsc::channel; use std::thread::Thread; fn main() { let

    (tx, rx) = channel(); for task_num in range(0u8, 8) { let tx = tx.clone(); // <-- will be captured by thread Thread::spawn(move || { let msg = format!("Task {:?} done!", task_num); tx.send(msg).unwrap(); }).detach(); } for _ in range(0u8, 8) { let data = rx.recv().unwrap(); println!("{:?}", data); } // 10x => Task N done! }