Slide 1

Slide 1 text

Rust For Serious Developers Armin @mitsuhiko Ronacher

Slide 2

Slide 2 text

)J *N"SNJO BOE*EP0QFO4PVSDF 'MBTL +JOKB 4FOUSZ j

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

Sentry Loves Rust

Slide 6

Slide 6 text

Symbolication

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Source Map Expansion

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

Command Line Tool

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

Hello Rust

Slide 13

Slide 13 text

Ocaml C++ Haskell Erlang Scheme C# ADT, Pattern Matching RAII, Smart Pointers Typeclasses Message Passing, Failures Hygienic Macros Attributes

Slide 14

Slide 14 text

fn main() { println!("Hello, World!"); }

Slide 15

Slide 15 text

The Toolchain

Slide 16

Slide 16 text

is so good

Slide 17

Slide 17 text

curl https://sh.rustup.rs -sSf | sh https://win.rustup.rs or on windows

Slide 18

Slide 18 text

rustup the rust toolchain manager

Slide 19

Slide 19 text

rustc the rust compiler

Slide 20

Slide 20 text

cargo the rust package manager

Slide 21

Slide 21 text

rustdoc the rust documentation builder

Slide 22

Slide 22 text

Quickstart

Slide 23

Slide 23 text

$ 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!

Slide 24

Slide 24 text

Release Channels

Slide 25

Slide 25 text

stable new release every 6 weeks

Slide 26

Slide 26 text

beta upcoming stable release

Slide 27

Slide 27 text

nightly includes unstable features

Slide 28

Slide 28 text

$ 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)

Slide 29

Slide 29 text

The Ecosystem

Slide 30

Slide 30 text

crates.io repository of reusable rust crates

Slide 31

Slide 31 text

docs.rs documentation for all crates

Slide 32

Slide 32 text

The Features

Slide 33

Slide 33 text

ADTs

Slide 34

Slide 34 text

enum JsonValue { Null, Bool(bool), Number(f64), Str(String), List(Box>), Object(Box>), }

Slide 35

Slide 35 text

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"); } } }

Slide 36

Slide 36 text

explicit error propagation

Slide 37

Slide 37 text

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(); }

Slide 38

Slide 38 text

strong types and inference

Slide 39

Slide 39 text

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::>(); 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

Slide 40

Slide 40 text

data vs behavior

Slide 41

Slide 41 text

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 } }

Slide 42

Slide 42 text

it's all about traits

Slide 43

Slide 43 text

use std::fmt; impl fmt::Debug for User { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "", &self.username, self.id) } }

Slide 44

Slide 44 text

compiler plugins

Slide 45

Slide 45 text

#[derive(Debug, Clone, Serialize, Deserialize)] struct User { id: u64, username: String, }

Slide 46

Slide 46 text

memory safety

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

so how does rust do it?

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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>, }

Slide 53

Slide 53 text

fn main() { let items = vec![1, 2, 3]; let sitems = items.into_iter().map(|x| x.to_string()).collect::>(); 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::>(); | ----- 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`, which does not implement the `Copy` trait error: aborting due to previous error

Slide 54

Slide 54 text

free parallelism

Slide 55

Slide 55 text

extern crate rayon; fn quick_sort(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(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

Slide 56

Slide 56 text

struct Server { ctx: Arc, } 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

Slide 57

Slide 57 text

Should you use it?

Slide 58

Slide 58 text

maybe!

Slide 59

Slide 59 text

Python Modules

Slide 60

Slide 60 text

Redis/Nginx Modules

Slide 61

Slide 61 text

Command Line Tools

Slide 62

Slide 62 text

Native Libraries

Slide 63

Slide 63 text

One-Trick-Pony API Servers

Slide 64

Slide 64 text

Our Experience

Slide 65

Slide 65 text

code is very readable

Slide 66

Slide 66 text

compile times suck

Slide 67

Slide 67 text

crate ecosystem is great

Slide 68

Slide 68 text

highly maintainable

Slide 69

Slide 69 text

QA &