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

Rust Language (#bcbk7)

Rust Language (#bcbk7)

Barcamp Bangkhen 7

Manatsawin Hanmongkolchai

November 13, 2016
Tweet

More Decks by Manatsawin Hanmongkolchai

Other Decks in Programming

Transcript

  1. Me • Manatsawin Hanmongkolchai • @awkwin • Software and Knowledge

    Engineering @ KU • Intern @ Wongnai • I've been learning Rust since February
  2. Friends of Rust “the advantages of Rust are many: really

    powerful abstractions, no null, no segfaults, no leaks, yet C-like performance and control over memory.” "Our preliminary measurements show the Rust component performing beautifully and delivering identical results to the original C++ component it’s replacing—but now implemented in a memory-safe programming language." "Rust has been the perfect tool for this job because it allowed us to offload an expensive operation into a native library without having to use C or C++, which would not be well suited for a task of this complexity. "
  3. Pattern matching switch(x){ case 1: printf("Hello"); break; case 2: printf("World");

    break; default: printf("Error"); } match x { 1 => println!("Hello"), 2 => println!("World"), _ => println!("Error"), }
  4. Pattern matching match x { Ok(1) => println!("Hello"), Ok(2) =>

    println!("World"), Error => println!("Error"), } enum Result { Ok(i32), Error } error[E0004]: non-exhaustive patterns: `Ok(_)` not covered --> <anon>:8:11 | 8 | match x { | ^ pattern `Ok(_)` not covered error: aborting due to previous error
  5. No more NullPointerException fn main() { let value: Option<i32> =

    None; println!("{}", value.unwrap()); } thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', ../src/libcore/option.rs:326 note: Run with `RUST_BACKTRACE=1` for a backtrace. You know exactly where panic can occur
  6. Other ways to deal with NPE match value { Some(x)

    => println!("{}", x), None => println!("Nothing"), } value.unwrap_or(5) Pattern matching Use a default value Some(String::from("Barcamp")).map(|s| s.len()); Apply a function
  7. Or do it in JavaScript style Some(x).and(Some(50)) Some(x).or(Some(50)) x &&

    50 === 50 x || 50 === x None.and(Some(50)) null && 50 === null None.or(Some(50)) null || 50 === 50
  8. Traits • Rust have no class • But we have

    struct and traits • Traits can require other traits to be implemented first
  9. Traits • Then we implement the trait impl Shop<Car> for

    CarShop { fn buy(&self) -> Car { Car{} } }
  10. Traits • We can implement trait for trait as well

    impl<T: Clone> Shop<T> for T { fn buy(&self) -> T { self.clone() } } fn main() { println!("{}", 64i32.buy()); }
  11. Traits • Note that traits must be imported before using.

    • Cannot implement traits declared outside of the crate to type declared outside of the crate
  12. Rust is safe Rule of Rust: 1. A resource have

    one owner let x = vec![1]; let y = x; println!("{}", x.len());
  13. Rust is safe error[E0382]: use of moved value: `x` -->

    <anon>:4:20 | 3 | let y = x; | - value moved here 4 | println!("{}", x.len()); | ^ value used here after move <std macros>:2:27: 2:58 note: in this expansion of format_args! <std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>) <anon>:4:5: 4:29 note: in this expansion of println! (defined in <std macros>) | = note: move occurs because `x` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait error: aborting due to previous error
  14. Rust is safe Note: Function call by value is a

    move fn handler(res: Response) { res.write(b"Hello World!"); res.end(); res.write(b"Write after closing"); } fn end(self)
  15. Rust is safe Rule of Rust: 1. A resource have

    one owner 2. Others can borrow it from the owner but the reference must last no longer than the owner let y; if true { let x = vec![1]; y = &x; } println!("{}", y.len());
  16. Rust is safe error: `x` does not live long enough

    --> <anon>:5:14 5 | y = &x; | ^ note: reference must be valid for the block suffix following statement 0 at 2:10... --> <anon>:2:11 2 | let y; | ^ note: ...but borrowed value is only valid for the block suffix following statement 0 at 4:24 --> <anon>:4:25 4 | let x = vec![1]; | ^
  17. Rust is safe Rule of Rust: 1. A resource have

    one owner 2. Others can borrow it from the owner but the borrow must last no longer than the owner 3. Only one mutable reference let mut x = vec![1]; x.push(5); let y = &x; y.push(6);
  18. Rust is safe error: cannot borrow immutable borrowed content `*y`

    as mutable --> <anon>:6:5 | 6 | y.push(6); | ^ error: aborting due to previous error
  19. Rust is safe Rule of Rust: 1. A resource have

    one owner 2. Others can borrow it from the owner but the borrow must last no longer than the owner 3. Only one mutable reference let mut x = vec![1]; x.push(5); let y = &mut x; x.push(6);
  20. Rust is safe error[E0499]: cannot borrow `x` as mutable more

    than once at a time --> <anon>:5:5 | 4 | let y = &mut x; | - first mutable borrow occurs here 5 | x.push(6); | ^ second mutable borrow occurs here 6 | } | - first borrow ends here
  21. Rust is safe What does this prevent? • Use after

    free: Rust use RAII plus lifetime check • Dangling pointers: Prevented by lifetime check • Rust also have no socket/file pointer closing function. Socket is closed when it goes out of scope.
  22. Rust is concurrent • Rust shines in concurrent programming •

    Rust provides ◦ Thread ◦ Reference counted type ◦ Mutex ◦ RwLock ◦ Atomic types ◦ Go-style message passing channel
  23. Rust is concurrent • Thread safely use std::thread; fn main()

    { let mut x = Box::new(5); // allocate 5 in the heap let child = thread::spawn(|| *x += 1); *x += 1; child.join().unwrap(); println!("{}", x); }
  24. Rust is concurrent error[E0373]: closure may outlive the current function,

    but it borrows `x`, which is owned by the current function --> <anon>:5:31 | 5 | let child = thread::spawn(|| *x += 1); | ^^ - `x` is borrowed here | | | may outlive borrowed value `x` | help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword, as shown: | let child = thread::spawn(move || *x += 1);
  25. Rust is concurrent use std::thread; fn main() { let mut

    x = Box::new(5); // allocate 5 in the heap let child = thread::spawn(move || *x += 1); *x += 1; child.join().unwrap(); println!("{}", x); }
  26. Rust is concurrent error[E0382]: use of moved value: `*x` -->

    <anon>:6:5 | 5 | let child = thread::spawn(move || *x += 1); | ------- value moved (into closure) here 6 | *x += 1; | ^^^^^^^ value used here after move | = note: move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
  27. Rust is concurrent use std::thread; use std::sync::Arc; use std::sync::Mutex; fn

    main() { let x = Arc::new(Mutex::new(5)); let y = x.clone(); let child = thread::spawn(move || { *(y.lock().unwrap()) += 1; }); {*(x.lock().unwrap()) += 1;} child.join().unwrap(); println!("{}", *(x.lock().unwrap())); }
  28. Rust is concurrent use std::thread; use std::sync::Arc; use std::sync::Mutex; fn

    main() { let x = Arc::new(Mutex::new(5)); let y = x.clone(); let child = thread::spawn(move || { *(y.lock().unwrap()) += 1; }); {*(x.lock().unwrap()) += 1;} child.join().unwrap(); println!("{}", *(x.lock().unwrap())); }
  29. Rust is concurrent use std::thread; use std::sync::Arc; use std::sync::Mutex; fn

    main() { let x = Arc::new(Mutex::new(5)); let y = x.clone(); let child = thread::spawn(move || { *(y.lock().unwrap()) += 1; }); {*(x.lock().unwrap()) += 1;} child.join().unwrap(); println!("{}", *(x.lock().unwrap())); }
  30. Rust is fast • Borrow check is done during compile

    time • Generic can be dispatched statically (like C++ templates) ◦ Rust has zero-cost abstraction as its core value: pay for only what you use • Rust have no garbage collection • Rust allocate all local variable on the stack
  31. Cargo • Rust's package manager • Also a build &

    test & benchmark tool • At this time of writing: 6,804 crates 84M downloads • arewewebyet.org • arewegameyet.org • /areweideyet.com
  32. Rust 1.13 • ? operator (Equivalent to wrapping with try!)

    ◦ try!(try!(try!(foo()).bar()).baz()) ◦ Is now foo()?.bar()?.baz()? • Macro can be used in place of type
  33. Project Quantum • Quantum is Mozilla's project to build the

    next-generation web engine for Firefox users, building on the Gecko engine as a solid foundation. • We're going to ship major improvements in 2017, and we'll iterate from there • https://wiki.mozilla.org/Quantum
  34. 2016 Rust Commercial Use Survey • https://internals.rust-lang.org/t/2016-rust-commercial-user-survey-results/4317 • Each of

    the 14 companies that responded is using Rust in their products. • Rust is very much a tool for general-purpose development where performance and safety matters. • Pain points ◦ Library support ◦ C++ FFI ◦ IDE Support ◦ Build time ◦ Learning curve for new developers