54
Rust

Rust-lang

Embed Size (px)

Citation preview

Page 1: Rust-lang

Rust

Page 2: Rust-lang

Anthony Broad-CrawfordCTO @ Fooda

Page 3: Rust-lang
Page 4: Rust-lang

Rust is a systems programming language that runs blazingly fast, prevents almost all crashes*, and eliminates data races.

Page 5: Rust-lang

rust

1. guaranteed memory safety2. threads without dataraces3. zero-cost abstractions (done at compile time)4. trait-based generics5. pattern matching6. type inference7. & more

Page 6: Rust-lang
Page 7: Rust-lang

Cargo is a tool that allows Rust projects to declare their various dependencies, and ensure that you'll always get a repeatable build.

Page 8: Rust-lang

and tests ...

Page 9: Rust-lang

cargo

1. introduces conventions over configuration2. declarative syntax for dependencies3. declarative syntax for compilation profiles4. easy execution of unit, integration, & benchmark

tests

Page 10: Rust-lang

our obligatory hello world

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

//> Cargo run//> Hello, world!//

Page 11: Rust-lang

let's go create a hello world with Cargo!

Page 12: Rust-lang

Using cargo to create projects

Rust's package manager

Usage: cargo <command> [<args>...] cargo [options]

Options: -h, --help Display this message -V, --version Print version info and exit --list List installed commands -v, --verbose Use verbose output

Some common cargo commands are: build Compile the current project clean Remove the target directory doc Build this project's and its dependencies' documentation new Create a new cargo project run Build and execute src/main.rs test Run the tests bench Run the benchmarks update Update dependencies listed in Cargo.lock

Page 13: Rust-lang

Primative types, Memory safety & zero cost abstractions

Page 14: Rust-lang

primatives

fn main() { //integers let i: i8 = 1; // i16, i32, i64, and i are available //unsigned let u: u8 = 2; // u16, u32, u64, and u are available //floats let f: f32 = 1.0; // f64 also available //booleans let b: bool = true; // false also available, duh //string and characters let c: char = 'a'; let s: &str = "hello world";}

Page 15: Rust-lang

variable bindings

fn main() {

let x: int = 1; //explicitly declare type let y = 2i; //type inference let (a,b,c) = (1i,2i,3i); //variable declaration via patterns let a = [1, 2, 3]; //array literals let s = "hello"; //string literal

println!("*_^ x = {}, y = {}, a,b,c = {},{},{}", x,y,a,b,c);}

//> Cargo run//> *_^ x = 1, y = 2, a,b,c = 1,2,3//

Page 16: Rust-lang

variable mutability

fn main() {

let x: int = 1; x = 10;

println!("The value of x is {}", x);}

//Cargo run//error: re-assignment of immutable variable `x`// x = 10;// ^~~~~~~

Page 17: Rust-lang

variable mutability

fn main() {

let mut x: int = 1; x = 10;

println!("The value of x is {}", x);}

//Cargo run//warning: value assigned to `x` is never read// let mut x: int = 1;// ^~~~~~~

Page 18: Rust-lang

The Rust compiler is SUPER helpful

fn main() {

let mut x: int = 1; x = 10;

println!("The value of x is {}", x);}

//Cargo run//warning: value assigned to `x` is never read// let mut x: int = 1;// ^~~~~~~

Page 19: Rust-lang

stack vs. heap

fn main() {

let y: int = 1; //allocated on the stack let x: Box<int> = Box::new(10); //allocated on the heap

println!("Heap {}, Stack {}", x, y);}

//> Cargo run//> Heap 10, Stack 1//

Page 20: Rust-lang

heap allocation creates pointers

fn main() {

let x: Box<int> = box 10; //allocated on the heap x = 11;

println!("The Heaps new value is {}, x");}

//Cargo run//error: mismatched types: expected `Box<int>`// x = 11;// ^~~~~~~

Page 21: Rust-lang

memory mutability

fn main() {

let x: Box<int> = box 10; //allocated on the heap *x = 11;

println!("The Heaps new value is {}, x");}

//Cargo run//error: cannot assign to immutable dereference of `*x`// x = 11;// ^~~~~~~

Page 22: Rust-lang

memory mutability

fn main() {

let mut x: Box<int> = box 10; //allocated on the heap *x = 11;

println!("The Heaps new value is {}, x");}

//> Cargo run//> The Heaps new value is 11//

Page 23: Rust-lang

compiler protects you by owning de-allocation

fn main() { let mut x: Box<int> = box::new(10); //allocated on the heap *x = 11;

println!("The Heaps new value is {}, x");

//Scope for x ends here so the compiler adds the de-allocation //free(x);}

//> Cargo run//> The Heaps new value is 11//

Page 24: Rust-lang

There is no garbage collection in Rust. The compiler observes the lifetime of a variable and de-allocates it where it is no longer used.

Page 25: Rust-lang

but these features don't sum to the promised memory safety

Page 26: Rust-lang

borrowing

fn main() { // x is the owner of the integer, which is memory on the stack. let x = 5;

// you may lend that resource to as many borrowers as you like let y = &x; let z = &x;

// functions can borrow too! foo(&x);

// we can do this alllllll day! let a = &x;}

Page 27: Rust-lang

ownership is singular

fn main() { let mut x = 5; let y = &mut x; //mutability only allows one borrower let z = &mut x; // ... no go}

//> Cargo build//> error: cannot borrow `x` as mutable more than once at a time// let z = &mut x;// ^~~~~~~~~~~~~~~

Page 28: Rust-lang

ownership can be transferred

fn main() { let x: Box<i32> = Box::new(5); let y = add_one(x);

println!("{}", y);}

fn add_one(mut num: Box<i32>) -> Box<i32> { *num += 1; num}

//> Cargo run//> 6//

Page 29: Rust-lang

ownership can be transferred back

fn main() { let mut x: Box<i32> = Box::new(5); x = add_one(x);

println!("{}", x);}

fn add_one(mut num: Box<i32>) -> Box<i32> { *num += 1; num}

//> Cargo run//> 6//

Page 30: Rust-lang

now THAT sums to to the promised memory safety and data race prevention

Page 31: Rust-lang

Other features of Rust

Page 32: Rust-lang

pattern matching

fn main() { let x = 5;

match x { 1 => println!("one"), 2 => println!("two"), 3 => println!("three"), 4 => println!("four"), 5 => println!("five"), _ => println!("something else"), }}

Page 33: Rust-lang

pattern matching

fn main() { let x = 5;

match x { 1 | 2 => println!("one or two"), 3 => println!("three"), 4 ... 7 => println!("4 through 7"), _ => println!("anything"), }}

Page 34: Rust-lang

pattern matching

fn main(){ struct Point { x: i32, y: i32, }

let origin = Point { x: 0, y: 0 };

match origin { Point { x: x, .. } => println!("x is {}", x), }}

//> Cargo run//> x is 0//

Page 35: Rust-lang

iterators & adapters

fn main(){ for i in range(1i, 10i).filter(|&x| x % 2 == 0) { println!("{}", i); }}

//> Cargo run//> 2//> 4//> 6//> 8

Page 36: Rust-lang

functions

//a function that takes and integer and returns an integerfn add_one(x: i32) -> i32 { x + 1}

fn main(){ println!("1 plus 1 is {}", add_one(1));}

//> Cargo run//> 1 plus 1 is 2//

Page 37: Rust-lang

closures

fn main() { let add_one = |x| { 1 + x };

println!("The sum of 5 plus 1 is {}.", add_one(5));}

//> Cargo run//> The sum of 5 plus 1 is 6.//

Page 38: Rust-lang

closures can be passed as params

//Generic function that takes a closure as an argumentfn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 { f(x) + f(x)}

fn main() { let result = twice(5, |x: i32| { x * x });

println!("And we have .... {}", result);}

//> Cargo run//> And we have .... 50//

Page 39: Rust-lang

traitsstruct Circle { x: f64, y: f64, radius: f64,}

trait HasArea { fn area(&self) -> f64;}

impl HasArea for Circle { fn area(&self) -> f64 { std::f64::consts::PI * (self.radius * self.radius) }}

fn main() { let c = Circle {x:0.0, y:1.0, radius: 2.0}; println!("The circles's radious is {}", c.area());}

Page 40: Rust-lang

traits with generics

trait HasArea { fn area(&self) -> f64;}

fn print_area<T: HasArea>(shape: T) { println!("This shape has an area of {}", shape.area());}

fn main() { let c = Circle {x:0.0, y:1.0, radius: 2.0}; print_area(c);}

//> Cargo run//> This shape has an area of 12.566371//

Page 41: Rust-lang

So ... no classes?

Page 42: Rust-lang

concurrency

fn print_message(){ println!("Hello from within a thread!");}

fn main() { spawn(print_message);}

//> Cargo run//> Hello from within a thread!//

Page 43: Rust-lang

concurrency and ownership

fn print_message(){ println!("Hello from within a thread!");}

fn main() { let x: int = 5; spawn(move || print_message); x = 10;}

//> Cargo run//> error: re-assignment of immutable variable `x`// x = 10; // ^~~~~~~

Page 44: Rust-lang

The promised land of the Rust compiler :)

Page 45: Rust-lang

Cargo also has support for testing

1. unit testing2. integration testing3. benchmark testing

Page 46: Rust-lang

testing

#[test]fn adding_one(){ let expected: int = 5; let actual: int = 4;

assert_eq!(expected,actual);}

//> Cargo Test//> running 1 tests//> test adding_one ... FAILED//

Page 47: Rust-lang

testing an expected failure

#[test]#[should_fail]fn adding_one(){ let expected: int = 5; let actual: int = 4;

assert_eq!(expected,actual);}

//> Cargo Test//> running 1 tests//> test adding_one ... OK//

Page 48: Rust-lang

making it pass

#[test]fn adding_one(){ let expected: int = 5; let actual: int = 5;

assert_eq!(expected,actual);}

//> Cargo Test//> running 1 tests//> test adding_one ... OK//

Page 49: Rust-lang

benchmark tests

#[bench] fn bench_add_two(b: &mut Bencher) {

let add_one = |x| { 1 + x };

b.iter(|| add_one(2)); }

//> Cargo Test//> running 1 tests//> test tests::bench_add_two ... bench: 1 ns/iter (+/- 0)//> test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured//

Page 50: Rust-lang

As promised Rust

1. guarantees memory safety2. threads without dataraces3. zero-cost abstractions (done at compile time)4. trait-based generics5. pattern matching6. type inference7. & more

Page 51: Rust-lang

additional links

1. http://www.rust-lang.org—Guide (nice intro)—Reference (deeper articles)

2. http://rustbyexample.com3. irc (super friendly and helpful lot)

Page 52: Rust-lang

lastlycurl -s https://static.rust-lang.org/rustup.sh | sudo sh

Page 53: Rust-lang

Questions?

Page 54: Rust-lang

Anthony Broad-Crawford@[email protected]

650.691.5107 (c)