Rust is a emerging system language with the speed of C/C++, the ergonomics of a functional language and the safety of a modern dynamic language. In this presentation I’ll expose the main feature of the language which make it distinctive and a good choice for fats and reliable software
5. Rust
● Static typed
● Compiled ahead of time
● Memory safety without Garbage Collector
● Abstractions without overhead
6. Rust
Project internally
started by Mozilla’s
employee in the 2009
First pre-alpha
release in January
2012
First stable release
1.0 on May 2015
Currently, March 2017,
at version 1.16
7. The aim of the language
is to be as fast as C/C++
but safer
and more expressive
13. Pattern Matching / 2
let x = ' ';
let y = 1;
match x {
'a' ... 'z' => println!("ASCII letter"),
_ => println!("something else"),
}
match y {
1 ... 10 => println!("1 through 10"),
5 ... 15 => println!("5 through 15"),
_ => println!("anything"),
}
14. Structs
struct Point {
x: i32,
y: i32,
}
fn main() {
let origin = Point { x: 0, y: 0 };
println!("The origin is at ({}, {})",
origin.x, origin.y);
}
Can have methods or Traits
15. Methods
struct Circle {
x: f64,
y: f64,
radius: f64,
}
impl Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * (self.radius * self.radius)
}
}
fn main() {
let c = Circle { x: 0.0, y: 0.0, radius: 2.0 };
println!("{}", c.area());
}
Methods are just functions attached to a struct
16. Traits
struct Square {
l: f64,
}
trait HasArea {
fn area(&self) -> f64;
}
impl HasArea for Square {
fn area(&self) -> f64 { self.l * self.l }
}
Traits are like interfaces; combine for polymorphism
17. Iterators
(1..)
.filter(|&x| x % 2 == 0)
.filter(|&x| x % 3 == 0)
.take(5)
.collect::<Vec<i32>>();
Iterators helps are used for functional programming
Functional programming is integrated within the language
19. Ownership / 1
let v = vec![1, 2, 3];
let v2 = v;
println!("v[0] is: {}", v[0]);
error: use of moved value: `v`
println!("v[0] is: {}", v[0]);
You cannot use a value owned by someone else
The compiler will throw an error for you
20. Ownership / 2
fn take(v: Vec<i32>) {
// what happens here isn’t important.
}
let v = vec![1, 2, 3];
take(v);
println!("v[0] is: {}", v[0]);
error: use of moved value: `v`
println!("v[0] is: {}", v[0]);
^
Passing by value move the ownership as well
21. Borrowing / 1
fn foo(v: &Vec<i32>) -> i32 {
// do stuff with v
}
let v = vec![1, 2, 3];
foo(&v);
println!("v[0] is: {}", v[0]); // it works
Avoid moving ownership by passing by reference
References are immutable
22. Borrowing / 2
fn bar(v: &mut Vec<i32>) {
v.push(4)
}
let mut v = vec![1, 2, 3];
bar(v);
println!("{}", v[0]); // [1, 2, 3, 4]
Mutable references allows you to mutate
23. Lifetimes / 1
struct Child {}
struct Parent {
child: &Child
}
let child = Child{};
let parent = Parent{child: &child};
error: missing lifetime specifier [E0106]
child: &Child
^~~~~~
Problem, when child goes out of scope parent will
point to freed memory
24. Lifetimes / 2
struct Child {}
struct Parent<'a> {
child: &'a Child
}
let child = Child{};
let parent = Parent{child: &child};
We declare a lifetime ‘a, the compiler will free the
memory of child when Parent’s memory is freed
27. ● Desugaring
● Reduce Rust to a simple core
● Create a control flow graph
● Simplify match expression, apply explicit drops and
panics
● Output LLVM IR
Optimisations
MIR: mid-level IR
28. MIR / 1
Simple Rust code...
for elem in vec {
process(elem);
}
29. MIR / 2
...converted into partial MIR
let mut iterator = IntoIterator::into_iter(vec);
loop:
match Iterator::next(&mut iterator) {
Some(elem) => { process(elem); goto loop; }
None => { goto break; }
}
break:
...
30. LLVM
● Applies 100+ between transformations and
optimisations
● Link-time optimisations
● Target multiple platforms: x86, ARM, WebAssembly
31. Final binary
● The final binary is statically compiled
● No need of pre-installed runtime
● Only system provided libraries are linked