SlideShare a Scribd company logo
Rust
About Rust
● New systems programming language by Mozilla.
● Designed to write secure code:
● Memory safety
● Thread safety
● Performance similar to C++
Hello, world!
fn main() {
println!(“Hello, world!”);
}
$ rustc hello.rs
$ ./hello
Hello, world!
Cargo
Cargo.toml
[package]
name = "program"
version = "0.1.0"
authors = ["John D <john.d@test.com>"]
[features]
default = [ ]
[dependencies]
num = "0.1.27"
Commands
$ cargo build
$ cargo test
$ cargo run
$ cargo new title [--bin]
Tool used for downloading dependencies, building dependencies and
building our program.
Syntax
fn increase(x: i32) -> i32 {
x + 1
}
fn swap(tuple: (i32, i32)) -> (i32, i32)
{
let (x, y) = tuple;
(y, x)
}
fn main() {
println!("{}", increase(10));
let my_tuple = (10, 20);
println!("{:?}", swap(my_tuple));
}
$ rustc syntax.rs
$ ./syntax
11
(20, 10)
Variable bindings
A 'let' expression is a pattern:
let(x, y) = (42, 24); // x = 42, y = 24
Variable bindings are immutable by default:
let x = 42;
x = 10;// error
let mut x = 42;
Type inference:
let x: i32 = 10; // Same as let x = 10;
Stack and Heap
fn main() {
let x = Box::new(5);
let y = 42;
let z = &x;
}
Box<T> implements Drop, it is freed when it goes out of
scope
Address Name Value
2^30
...
5
2 z → 0
1 y 42
0 x → 2^30
Vector
● Provided by the std library
● Growable (dynamic)
● Can implement any type: Vec<T>
let v = vec![1, 2, 3, 4, 5]; // v: Vec<i32>
let mut my_vector: Vec<u8> = Vec::new();
let v = vec![0; 10];
for i in &v {
println!("Reference to {}", i);
}
for point in fractal.iter() {
if *point == 0 {…}
}
Structs and enums
STRUCT
struct Color {r: i32, g: i32, b: i32 }
fn main() {
let mut color: Color = Color { r: 255, g: 0, b: 0 };
color.g = 255;
println!("r: {}, g: {}, b: {}", color.r, color.g, color.b);
}
ENUM
#[derive(Debug)]
enum OperationError {
DivisionByZero,
UnexpextedError,
Indetermination,
}
fn division(n: f64, d: f64) -> Result<f64, OperationError> {...}
Pattern matching
let x = 3;
match x {
1 => println!("one"),
2 | 3 => println!("two or three"),
x @ 4..10 => println!(“say {}”, x),
_ => println!("i can't count that much"),
}
Result<T, E>
To manage errors, we can use the type system:
enum Result<T, E> {
Ok(T),
Err(E)
}
// Result<T, String>
fn division(num: f64, den: f64) -> Result<f64, String> {
if den == 0.0 {
Err(“Error”)
} else {
Ok(num / den)
}
}
Ownership
Variable bindings imply there is an owner to an asset
fn foo() {
let v = vec![1, 2, 3];
}
1) v in scope: Vec<i32> is created
2) Vector lives in the heap
3) Scope ends: v is freed, heap
allocated vector is cleaned.
There is only one binding to any asset. Lifetimes and transferring
ownership must be considered.
fn read_vector(vec: Vec<i32>) {
println!("{:?}", vec);
}
fn main() {
let my_vector = vec!(1, 3, 5, 7);
read_vector(my_vector);
println!("{:?}", my_vector); // error
}
Ownership
Give back ownership:
fn read_vector(vec: Vec<i32>) -> Vec<i32> {
println!("{:?}", vec);
vec
}
Borrowing (pass by reference):
fn read_vector(vec: &Vec<i32>) {
println!("{:?}", vec);
}
fn main() {
let my_vector = vec!(1, 3, 5, 7);
...
}
Ownership
Mutable reference: &mut
fn add_to_vector(vec: &mut Vec<i32>) {
vec.push(10);
}
fn main() {
let mut my_vector = vec!(1, 3, 5, 7);
add_to_vector(&mut my_vector);
println!("{:?}", my_vector);
}
● Any borrow's scope may not last longer than the owner
● Can exist many immutable borrows, (&x)
● Only one mutable reference (&mut x)
Traits
// TRAIT: Tells about a functionality a type has to provide
trait Dimensional {
fn area(&self) -> i32;
}
// Function for any type that implements the Dimensional trait
fn print_area<T: Dimensional>(object: T) {
println!("Area: {}", object.area());
}
struct Rectangle {x1: i32, y1: i32, x2: i32, y2: i32,}
impl Dimensional for Rectangle {
fn area(&self) -> i32 {
(self.x2 - self.x1) * (self.y2 - self.y1)
}
}
fn main() {
let r = Rectangle { x1: 0, x2: 4, y1: 0, y2: 2, };
print_area(r);
}
Closures
● Anonymous functions
● Rust imposes less restrictions about type annotations:
● Argument types and return types can be inferred
● May be multi-line, with statements between { }
fn main() {
let multiply = |x, y| x * y;
let sum_squares = |x: i32, y: i32| -> i32 {
let x = x * x;
let y = y * y;
x + y
};
println!("{:?}", multiply(2, 3));
println!("{:?}", sum_squares(2, 3));
}
Threading (spawning)
● A thread can be spawned with thread::spawn
● Accepts a closure and returns a handle
● Handles can be error checked with the Result Enum
use std::thread;
fn main() {
let handle = thread::spawn(|| "Hello".to_string());
match handle.join() {
Ok(x) => println!("{}", x),
Err(e) => println!("{:?}", e),
}
}
Other features
● Foreign Function Interface in 2 directions:
● Can call C code into Rust
● Can call Rust into other programs
● Conditional compilation by passing flags and assisted by Cargo
[features]
secure-password = ["bcrypt"]
● Use of 'raw pointers' (marked as unsafe to the compiler)
let x = 5;
let raw = &x as *const i32;
let points_at = unsafe { *raw };
println!("raw points at {}", points_at);
Rust projects
● Maidsafe (http://maidsafe.net/)
“ MaidSafe is a fully decentralized platform on which
application developers can build decentralized applications”
● Crates.io (https://crates.io/)
A catalog with Rust crates
● Servo (https://github.com/servo/servo)
“Servo is a prototype web browser engine written in the Rust
language. It is currently developed on 64bit OS X, 64bit Linux,
Android, and Gonk (Firefox OS).”

More Related Content

Short intro to the Rust language

  • 2. About Rust ● New systems programming language by Mozilla. ● Designed to write secure code: ● Memory safety ● Thread safety ● Performance similar to C++
  • 3. Hello, world! fn main() { println!(“Hello, world!”); } $ rustc hello.rs $ ./hello Hello, world!
  • 4. Cargo Cargo.toml [package] name = "program" version = "0.1.0" authors = ["John D <john.d@test.com>"] [features] default = [ ] [dependencies] num = "0.1.27" Commands $ cargo build $ cargo test $ cargo run $ cargo new title [--bin] Tool used for downloading dependencies, building dependencies and building our program.
  • 5. Syntax fn increase(x: i32) -> i32 { x + 1 } fn swap(tuple: (i32, i32)) -> (i32, i32) { let (x, y) = tuple; (y, x) } fn main() { println!("{}", increase(10)); let my_tuple = (10, 20); println!("{:?}", swap(my_tuple)); } $ rustc syntax.rs $ ./syntax 11 (20, 10)
  • 6. Variable bindings A 'let' expression is a pattern: let(x, y) = (42, 24); // x = 42, y = 24 Variable bindings are immutable by default: let x = 42; x = 10;// error let mut x = 42; Type inference: let x: i32 = 10; // Same as let x = 10;
  • 7. Stack and Heap fn main() { let x = Box::new(5); let y = 42; let z = &x; } Box<T> implements Drop, it is freed when it goes out of scope Address Name Value 2^30 ... 5 2 z → 0 1 y 42 0 x → 2^30
  • 8. Vector ● Provided by the std library ● Growable (dynamic) ● Can implement any type: Vec<T> let v = vec![1, 2, 3, 4, 5]; // v: Vec<i32> let mut my_vector: Vec<u8> = Vec::new(); let v = vec![0; 10]; for i in &v { println!("Reference to {}", i); } for point in fractal.iter() { if *point == 0 {…} }
  • 9. Structs and enums STRUCT struct Color {r: i32, g: i32, b: i32 } fn main() { let mut color: Color = Color { r: 255, g: 0, b: 0 }; color.g = 255; println!("r: {}, g: {}, b: {}", color.r, color.g, color.b); } ENUM #[derive(Debug)] enum OperationError { DivisionByZero, UnexpextedError, Indetermination, } fn division(n: f64, d: f64) -> Result<f64, OperationError> {...}
  • 10. Pattern matching let x = 3; match x { 1 => println!("one"), 2 | 3 => println!("two or three"), x @ 4..10 => println!(“say {}”, x), _ => println!("i can't count that much"), }
  • 11. Result<T, E> To manage errors, we can use the type system: enum Result<T, E> { Ok(T), Err(E) } // Result<T, String> fn division(num: f64, den: f64) -> Result<f64, String> { if den == 0.0 { Err(“Error”) } else { Ok(num / den) } }
  • 12. Ownership Variable bindings imply there is an owner to an asset fn foo() { let v = vec![1, 2, 3]; } 1) v in scope: Vec<i32> is created 2) Vector lives in the heap 3) Scope ends: v is freed, heap allocated vector is cleaned. There is only one binding to any asset. Lifetimes and transferring ownership must be considered. fn read_vector(vec: Vec<i32>) { println!("{:?}", vec); } fn main() { let my_vector = vec!(1, 3, 5, 7); read_vector(my_vector); println!("{:?}", my_vector); // error }
  • 13. Ownership Give back ownership: fn read_vector(vec: Vec<i32>) -> Vec<i32> { println!("{:?}", vec); vec } Borrowing (pass by reference): fn read_vector(vec: &Vec<i32>) { println!("{:?}", vec); } fn main() { let my_vector = vec!(1, 3, 5, 7); ... }
  • 14. Ownership Mutable reference: &mut fn add_to_vector(vec: &mut Vec<i32>) { vec.push(10); } fn main() { let mut my_vector = vec!(1, 3, 5, 7); add_to_vector(&mut my_vector); println!("{:?}", my_vector); } ● Any borrow's scope may not last longer than the owner ● Can exist many immutable borrows, (&x) ● Only one mutable reference (&mut x)
  • 15. Traits // TRAIT: Tells about a functionality a type has to provide trait Dimensional { fn area(&self) -> i32; } // Function for any type that implements the Dimensional trait fn print_area<T: Dimensional>(object: T) { println!("Area: {}", object.area()); } struct Rectangle {x1: i32, y1: i32, x2: i32, y2: i32,} impl Dimensional for Rectangle { fn area(&self) -> i32 { (self.x2 - self.x1) * (self.y2 - self.y1) } } fn main() { let r = Rectangle { x1: 0, x2: 4, y1: 0, y2: 2, }; print_area(r); }
  • 16. Closures ● Anonymous functions ● Rust imposes less restrictions about type annotations: ● Argument types and return types can be inferred ● May be multi-line, with statements between { } fn main() { let multiply = |x, y| x * y; let sum_squares = |x: i32, y: i32| -> i32 { let x = x * x; let y = y * y; x + y }; println!("{:?}", multiply(2, 3)); println!("{:?}", sum_squares(2, 3)); }
  • 17. Threading (spawning) ● A thread can be spawned with thread::spawn ● Accepts a closure and returns a handle ● Handles can be error checked with the Result Enum use std::thread; fn main() { let handle = thread::spawn(|| "Hello".to_string()); match handle.join() { Ok(x) => println!("{}", x), Err(e) => println!("{:?}", e), } }
  • 18. Other features ● Foreign Function Interface in 2 directions: ● Can call C code into Rust ● Can call Rust into other programs ● Conditional compilation by passing flags and assisted by Cargo [features] secure-password = ["bcrypt"] ● Use of 'raw pointers' (marked as unsafe to the compiler) let x = 5; let raw = &x as *const i32; let points_at = unsafe { *raw }; println!("raw points at {}", points_at);
  • 19. Rust projects ● Maidsafe (http://maidsafe.net/) “ MaidSafe is a fully decentralized platform on which application developers can build decentralized applications” ● Crates.io (https://crates.io/) A catalog with Rust crates ● Servo (https://github.com/servo/servo) “Servo is a prototype web browser engine written in the Rust language. It is currently developed on 64bit OS X, 64bit Linux, Android, and Gonk (Firefox OS).”