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

A Year of Rust

A Year of Rust

Rust is a systems programming language with a focus on safety. I started learning Rust a year ago when I was looking for a different backend stack (I had been using PHP previously). Using Rust as a web language for a year taught me many things that I had not learned using other languages.

In this talk, I’ll take you on a journey of what Rust taught me about programming and life. You will learn about subjects like the importance of composition, why object ownership is critical skill, and how Rust can give you more flexibility in your life.

Steve Zeidner

January 12, 2018
Tweet

More Decks by Steve Zeidner

Other Decks in Programming

Transcript

  1. Common Software Bugs • Memory Leaks • Null Pointer Exceptions

    • Buffer Overflows • Race conditions • Deadlocks
  2. } alarm(0); break; } if (i >= 6) return 0;

    /* 978 */ for(i = 0; i < 536; i++) /* 628,654 */ buf[i] = '\0'; for(i = 0; i < 400; i++) buf[i] = 1; for(j = 0; j < 28; j++) buf[i+j] = "\335\217/sh\0\335\217/bin\320^Z\335\0\ 335\0\335Z\335\003\320^\\\274; \344\371\344\342\241\256\343\350\357\25 6\362\351"[j]; /* constant string x200a0 */ /* 0xdd8f2f73,0x6800dd8f,0x2f62696e,0xd05e5add, 0x00dd00dd,0x5add03d0,0x5e5cbc3b */ https://github.com/arialdomartini/morris-worm Security Challenges
  3. Rust Design Goals • Syntax similar to C with zero-cost

    abstractions • Memory safe • Smart memory management • Inferred type system • Ownership, moves, borrows checked at compile time
  4. Safety • What does safety mean? • What do we

    mean by type safety? What are we being kept safe from?
  5. Undefined Behavior int main(int argc, char **argv) { unsigned long

    a[1]; a[3] = 0x7ffff7b36cebUL; return 0; }
  6. Terms • Well defined - A program has been written

    so that no possible execution can exhibit undefined behavior • Type Safe - A language's type system ensures that every program is well- defined
  7. Type Safety fn main() { let a = 123; a

    = "this is a string"; } error[E0308]: mismatched types --> src/main.rs:3:9 | 3 | a = "this is a string"; | ^^^^^^^^^^^^^^^^^^ expected integral variable, found reference | = note: expected type `{integer}` found type `&'static str` = help: here are some functions which might fulfill your needs: - .len()
  8. What does it actually mean to be safe? • The

    need for certainty • What about the unsafe keyword in Rust? fn index_of(&self, item: &T) -> Option<usize> { let ptr = item as *const T; unsafe { if self.as_ptr() < ptr && self.as_ptr(). offset(self.len() as isize) > ptr { Some(self.index_of_unchecked(item)) } else { None } } }
  9. Generics /// Given two values, pick whichever one is less.

    fn min<T: Ord>(value1: T, value2: T) -> T { if value1 <= value2 { value1 } else { value2 } }
  10. Traits and Composition struct Sheep { sheared: bool, name: &'static

    str } trait Animal { // Static method signature; `Self` refers to the implementor type. fn new(name: &'static str) -> Self; // Instance method signatures; these will return a string. fn name(&self) -> &'static str; fn noise(&self) -> &'static str; // Traits can provide default method definitions. fn talk(&self) { println!("{} says {}", self.name(), self.noise()); } }
  11. Traits and Composition impl Sheep { fn is_sheared(&self) -> bool

    { self.sheared } fn shear(&mut self) { if self.is_sheared() { // Implementor methods can use the implementor's trait methods. println!("{} is already sheared...", self.name()); } else { println!("{} gets a haircut!", self.name); self.naked = true; } } }
  12. Traits and Composition // Implement the `Animal` trait for `Sheep`.

    impl Animal for Sheep { // `Self` is the implementor type: `Sheep`. fn new(name: &'static str) -> Sheep { Sheep { name: name, sheared: false } } fn name(&self) -> &'static str { self.name } fn noise(&self) -> &'static str { if self.is_sheared() { "baaaaah?" } else { "baaaaah!" } } // Default trait methods can be overridden. fn talk(&self) { // For example, we can add some quiet contemplation. println!("{} pauses briefly... {}", self. name, self.noise()); } }
  13. Trait Bounds /// Print out all the values produced by

    an iterator fn dump<I>(iter: I) where I: Iterator { for (index, value) in iter.enumerate() { println!("{}: {:?}", index, value); // error } } error[E0277]: the trait bound `<I as std::iter::Iterator>::Item: std::fmt::Debug` is not satisfied --> traits_dump.rs:10:37 | 10 | println!("{}: {:?}", index, value); // error | ^^^^^ the trait `std::fmt::Debug` is not implemented | for `<I as std::iter::Iterator>::Item` | = help: consider adding a `where <I as std::iter::Iterator>::Item: std::fmt::Debug` bound = note: required by `std::fmt::Debug::fmt`
  14. Things I Learned from Rust • Rust Community: Community and

    support is key • Memory Safety: The importance of finding peace in an uncertain world • Traits: Setting proper goal posts for myself and others • Inspiration to take on more freelance work
  15. • Memory Leaks - ownership system ensures no memory leaks

    • Null Pointer Exceptions - lifetime check at compile time • Race conditions and Deadlocks - prevented with ownership system • Buffer Overflows - type safety ensures memory safe programs Does Rust allow us to write fast, secure software that doesn't crash?
  16. Learn Rust • Read: Programming Rust • Attend a meetup:

    Columbus Rust Society • Try it out: https://play.rust-lang.org/ • Practice: https://adventofcode.com/