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

Rust for Serious Developers

Rust for Serious Developers

An introduction for what Rust is, what makes it special and why it's not just a toy language but solving some real problems and will become an important tool of every technology stack.

Armin Ronacher

March 01, 2017

Transcript

69 slides
  1. Ocaml C++ Haskell Erlang Scheme C# ADT, Pattern Matching RAII,

    Smart Pointers Typeclasses Message Passing, Failures Hygienic Macros Attributes
  2. $ cargo new --bin hello-rust Created binary (application) `hello-rust` project

    $ cd hello-rust $ cargo run Compiling hello-rust v0.1.0 (file:///private/tmp/hello-rust) Finished debug [unoptimized + debuginfo] target(s) Running `target/debug/hello-rust` Hello, world!
  3. $ rustup override set nightly info: using existing install for

    'nightly-x86_64-apple-darwin' info: override toolchain for '/private/tmp/hello-rust' set to 'nightly-x86_64-apple-darwin' nightly-x86_64-apple-darwin unchanged - rustc 1.17.0-nightly (0648517fa 2017-02-27)
  4. fn main() { let value = JsonValue::Str("Hello World!".to_string()); match value

    { JsonValue::Str(ref string) => { println!("JSON value as a string: {}", string); }, _ => { println!("JSON value was something else"); } } }
  5. use std::{fs, env, io}; fn list_current_dir() -> Result<(), io::Error> {

    let here = env::current_dir()?; for dent_rv in fs::read_dir(here)? { let dent = dent_rv?; let md = dent.metadata()?; println!("{: <60}{: <12}{}", dent.path().display(), md.len(), if md.is_file() { "file" } else { "dir" }); } Ok(()) } fn main() { list_current_dir().unwrap(); }
  6. use std::{fs, env, io}; use std::collections::HashMap; fn count_extensions() -> Result<(),

    io::Error> { let mut counts = HashMap::new(); for dent_rv in fs::read_dir(env::current_dir()?)? { if let Some(ext) = dent_rv?.path().extension() { *counts.entry(ext.to_string_lossy().into_owned()).or_insert(0) += 1; } } let mut items = counts.into_iter().collect::<Vec<_>>(); items.sort_by_key(|&(_, value)| -value); for (ext, count) in items { println!("{: >5} {}", count, ext); } Ok(()) } Result Type OS Str -> String Hash Table Entry Vector of Tuples
  7. struct User { id: u64, username: String, } impl User

    { fn new(id: u64, username: &str) -> User { User { id: id, username: username.to_string(), } } fn username(&self) -> &str { &self.username } }
  8. use std::fmt; impl fmt::Debug for User { fn fmt(&self, f:

    &mut fmt::Formatter) -> fmt::Result { write!(f, "<User {} (id={})>", &self.username, self.id) } }
  9. lifetimes move semantics ADTs smart pointers bounds checking explicit unsafe

    Reason about Memory Track where stuff goes No Null-Pointers Runtime Lifetimes Panic on OOB The Escape Hatch
  10. struct SdkInfo { name: String, version: String, } struct SdkInfo<'a>

    { name: &'a str, version: &'a str, } struct SdkInfo<'a> { name: Cow<'a, str>, version: Cow<'a, str>, }
  11. fn main() { let items = vec![1, 2, 3]; let

    sitems = items.into_iter().map(|x| x.to_string()).collect::<Vec<_>>(); println!("Converted {} items to strings", items.len()); } error[E0382]: use of moved value: `items` --> fail.rs:4:46 | 3 | let sitems = items.into_iter().map(|x| x.to_string()).collect::<Vec<_>>(); | ----- value moved here 4 | println!("Converted {} items to strings", items.len()); | ^^^^^ value used here after move | = note: move occurs because `items` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait error: aborting due to previous error
  12. extern crate rayon; fn quick_sort<T: PartialOrd + Send>(v: &mut [T])

    { if v.len() > 1 { let mid = partition(v); let (low, high) = v.split_at_mut(mid); rayon::join(|| quick_sort(low), || quick_sort(high)); } } fn partition<T: PartialOrd + Send>(xs: &mut [T]) -> usize { let pivot = xs.len() - 1; let mut i = 0; for j in 0..pivot { if xs[j] <= xs[pivot] { xs.swap(i, j); i += 1; } } xs.swap(i, pivot); i } Values that order & can be sent to threads Spawn two threads and join split mutable slice into two
  13. struct Server { ctx: Arc<Context>, } impl Server { pub

    fn run(&self) -> Result<()> { let ctx = self.ctx.clone(); Server::http("127.0.0.1:3000")? .handle(move |req: Request, resp: Response| { let local_ctx = ctx.clone(); ... } } } increments refcount and returns new Arc

More Decks by Armin Ronacher

Other Decks in Programming