The Rust
Programming Language
Safe - Concurrent - Fast
By - Davis Silverman
fn main() {
println!("Hello, World!");
}
Who am I?
- Some PL geek
- Video game developer hobbyist
What Is Rust?
- Modern Idioms, the best of all worlds
- Immutable by default
- No null pointers
- Zero Cost Abstractions
- Strong ownership model
- move semantics -- think affine types
- pass by value (which includes references)
- Memory safe without garbage collection
- Library provided smart pointers
- Hygienic Macros
- Type-safe meta-programming
An Introduction
- No implicit casting
- Readable and precise grammar
- Powerful pattern matching
fn fizzbuzz(num: uint) -> String {
match (num % 3, num % 5) {
(0, 0) => "FizzBuzz".to_string(),
(0, _) => "Fizz".to_string(),
(_, 0) => "Buzz".to_string(),
(_, _) => num.to_string()
}
}
fn main() -> () {
for num in range(0u, 101) {
println!("{}", fizzbuzz(num));
}
}
Whoa Whoa Whoa.
2 STRING TYPES?!?!?!
- &'str is a reference, no allocation
- String is an owned object, allocated on the heap
- Think StringBuilder
Nouns and Verbs
struct Dog {
name: String,
age: uint,
}
impl Dog {
fn new(name: String, age: uint) -> Dog {
Dog { name:name, age:age }
}
fn bark(&self) -> String {
format!("I am dog {}. I am {}", self.name, self.age)
}
}
fn main() -> () {
let hunter_dawg: Dog = Dog::new("Hunter".to_string(), 5);
println!("{}", hunter_dawg.bark())
}
Note: using `format!` could allocate more than you want, using `write!` with a MemWriter could save more memory :)
Algebraic Data Types
- For Strongly Typed Data (HTTP Headers)
#[deriving(Show)]
enum List<T> {
Cons(T, Box<List<T>>),
Nil,
}
fn main() {
let list: List<i32> = Cons(1i32, box Cons(2, box Cons(3, box Nil)));
println!("{}", list);
}
Ownership
- Moves
- References
- Aliasing
/// This function takes ownership of the variable
fn move_and_destroy<T: std::fmt::Show>(c: T) {
// Have to return it to be claimed again.
println!("destroying a variable that contains {}" , c);
// `c` will be destroyed in this scope, and the memory will be freed
}
///this function prints the value of d
fn borrow_variable<T: std::fmt::Show>(d: &T) {
// Do not have to return the variable to let the caller reclaim it
println!("variable, {} is borrowed!" , d);
}
///this function alters f
fn borrow_mut_variable(f: &mut f64) {
*f = 42.0;
}
Named lifetimes
- Intentionally explicit
- To codify how long a reference is valid
- Simpler than you think
#[deriving(Show, PartialEq)]
enum Token<'a> {
Word(&'a str),
Other(&'a str)
}
fn tokenize_string3<'a>(text: &'a str) -> Vec<Token<'a>> {
let mut result = vec![];
for cap in regex!(r"(\w+)|(\W+)").captures_iter(text) {
let token =
if cap.pos(1).is_some() {
Word(cap.at(1))
} else {
Other(cap.at(2))
};
result.push(token);
}
result
}
http://www.randomhacks.net/2014/09/19/rust-lifetimes-reckless-cxx/
Zero Cost Abstractions
'Monomorphization'
fn print_area<T: HasArea>(shape: T) {
println!("This shape has an area of {}", shape.area());
}
fn main() {
let c = Circle { ... };
let s = Square { ... };
print_area(c);
print_area(s);
}
Boxes
- Not as necessary as you think
- If you can deal with lifetimes...
- Stack allocation > all
Demo?
meta.
Cool Rust stuff
- Piston - game libraries
- Rust-Postgres - great macro usage
- Bindings to like any C library! Free FFI
Text
Thanks!!!
- sinistersnare @ gmail
- questions?!
The Rust Programming Language
By Davis Silverman
The Rust Programming Language
- 3,777