Rust
Rust
Rust
Nolan
Davidson
Chef Software
Goals
What is Rust?
Talk about things that are awesome
Talk about challenges
Look at some tooling
Look at ways to dive in
Learn Rust
www.rust-lang.org
*Disclaimer*
The following properties apply to pure, safe Rust.
You can write *unsafe* Rust, which voids these guarantees.
Currently, many libraries are bindings to C libraries.
Compiled
Memory safe
Not garbage collected
Thread safe
Multi-paradigm
Focused on zero cost abstractions
History of Rust
Mozilla
First preRust
begins
alpha
announced
sponsoring
release
2009
2010
2012
Rust 1.0
2015
Ownership
Rust is memory safe without garbage collection.
This is an example of a zero-cost abstraction.
The Rust compiler will enforce ownership at compile time, the
run time performance will be as if we had allocated and
deallocated every thing manually.
These rules also apply to threaded operations.
Ownership
Variable bindings have ownership of the thing they are
bound to.
let name = Nolan".to_string(); // Binds value to name
Ownership
fn main() {
let string = "Hello world!".to_string();
let big_string = make_it_big(string);
println!("Original string: {}", string);
println!("Uppercase string: {}", big_string);
}
fn make_it_big(s: String) -> String {
s.to_uppercase()
}
References
If we use references, we can borrow the values rather than
changing ownership.
fn main() {
let string = "Hello world!".to_string();
let big_string = make_it_big(&string);
println!("Original string: {}", string);
println!("Uppercase string: {}", big_string);
}
fn make_it_big(s: &String) -> String {
s.to_uppercase()
}
Copy types
Some types implement the Copy trait. Copy types will
create a copy of the data instead of passing ownership.
Integers implement the Copy trait.
fn main() {
let i: i32 = 10;
let double_i = double_it(i);
println!("i is {}", i);
println!("i doubled is {}", double_i);
}
fn double_it(i: i32) -> i32 {
i * 2
}
Immutability is Standard
Variable bindings are immutable by default.
fn main() {
// Error
let i = 10;
i = 20;
// Correct
let mut i = 10;
i = 20;
}
This is great for keeping track of where you are mutating state.
Is it OO?
Rust does not currently implement a true object oriented
system.
We use structs combined with traits to achieve some OO
objectives.
This is system is focused on composition, rather than
inheritance. There is an open RFC about adding inheritance,
so stay tuned.
Traits
struct Circle { radius: f64 }
struct Square { side: f64 }
trait Shape {
fn area(&self) -> f64;
fn perimter(&self) -> f64;
}
impl Shape for Circle {
fn area(&self) -> f64 { std::f64::consts::PI * (self.radius * self.radius) }
fn perimter(&self) -> f64 { 2.0 * std::f64::consts::PI * self.radius }
}
impl Shape for Square {
fn area(&self) -> f64 { self.side * self.side }
fn perimter(&self) -> f64 { self.side * 4.0 }
}
fn print_shape<T: Shape>(shape: T) {
println!("Area is {}", shape.area());
}
fn main() {
let c = Circle { radius: 1.0 };
let s = Square { side: 2.0 };
print_shape(c);
print_shape(s);
}
Error handling
The preference is to handle errors by return values, rather than
exceptions.
The Rust standard library provides two built in types for doing
this: Option and Result.
Option returns either Some() or None(), to allow for possibility
of no value. Result expands on this by returning either Ok() or
Err(), taking into account error conditions.
Error handling
use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
fn main() {
let path = Path::new("myfile.txt");
let mut file = match File::open(&path) {
Err(e) => panic!("Could not open file!"),
Ok(file) => file,
};
let mut s = String::new();
match file.read_to_string(&mut s) {
Err(e) => println!("couldn't read the file!"),
Ok(_) => println!("file contains \n{}", s),
};
}
Tooling
crates.io
Repository for Rust packages (crates)
Crates are shared as source.
Used by the cargo tool.
Cargo
Package manager
Build tool
Cargo
cargo new - generates a new project
cargo build - compiles the current project
cargo run - compiles and run the current project
cargo publish - publish crate to crates.io
cargo test - run tests
Cargo
Cargo.toml
[package]
name = "my_app"
version = "0.1.0"
authors = ["Nolan Davidson <ndavidson@chef.io>"]
[dependencies]
rand = 0.3.0
Rustup
Tool for managing multiple versions of Rust.
Great for testing against multiple versions and experimenting
with nightly build features.
Other tools
rustfmt - Apply Rust style
racer - Code completion
clippy - Linting
Various editor plugins.