2. So, you want more control?
C++?
OMG!
2
Too slow!
Other things you might want:!
• Standalone library, as you would get from C
• Interface with another runtime, e.g. Ruby
• Use a really cool language :)
3. My god, it’s full of bugs
3
Dangling pointers
!
Segmentation faults
!
Double frees
!
Uninitialized data
!
Null pointer exceptions
!
Resource leaks (DB handle)
!
Data races
Solved by GC
Not so much.
5. // sums all the positive values in `v`
fn sum_pos(v: &Vec<i32>) -> i32 {
let mut sum = 0;
for i in v.iter().filter(|i| **i > 0) {
sum += *i;
}
sum
}
High-level coding
5
Iterators.
Closures.
8. Safe
8
fn this_wont_compile(v: &mut Vec<i32>) -> i32 {
let mut sum = 0;
for &i in v.iter() {
sum += i;
if i > 0 { v.push(0); }
}
sum
}
error: cannot borrow `*v` as mutable because it is also borrowed
as immutable
if i > 0 { v.push(0); }
^
note: previous borrow of `*v` occurs here; the immutable borrow
prevents subsequent moves or mutable borrows of `*v` until
the borrow ends
for &i in v.iter() {
^
Might free
underlying buffer.
9. Parallel
9
use std::thread;
fn qsort(data: &mut [i32])
if data.len() <= 1 {
return;
}
let mid = partition(data[0], data);
let (left, right) = data.split_at_mut(mid);
let t1 = thread::scoped(|| qsort(left));
qsort(right);
}
Sort left and right
in parallel.Caveat: unstable API.
10. Open and welcoming
Rust has been open source from the beginning.
!
Open governance model based on public RFCs.
!
We have an active, amazing community.
❤
10
11. Getting Started
11
You can either install Rust, or
just use play.rust-lang.org
Exercises are available at:
!
http://nikomatsakis.github.io/rust-tutorial-boston-20150722/
12. Outline
12
1. The big ideas:!
a. Ownership
b. Borrowing
2. Everyday life:!
a. Data types
b. Modules and privacy
c. Cargo
13. Ownership!
!
n. The act, state, or right of possessing something.
13
Borrow!
!
v. To receive something with the promise of returning it.
14. The Big Idea
Ownership and borrowing:!
!
1. All memory has a clear owner.
2. Others can borrow from the owner.
3. Owner cannot free or mutate the
memory while it is borrowed.
14
21. Mutability
21
fn prefix_sum(mut v: Vec<i32>) -> Vec<i32> {
let mut sum = 0;
for i in 0 .. v.len() {
sum += v[i];
v[i] = sum;
}
v
}
http://is.gd/wCtQQZ
1, 2, 3, 4 1, 3, 6, 10
(caller) (prefix sum)
22. Clone
22
fn main() {
let d = vec![1, 3, 4, 10];
let ps = prefix_sum(d);
println!("prefix sum of {:?} is {:?}",
d, ps);
}
http://is.gd/nbuxdV
23. Clone
23
fn main() {
let d = vec![1, 3, 4, 10];
let ps = prefix_sum(d.clone());
println!("prefix sum of {:?} is {:?}",
d, ps);
}
http://is.gd/nbuxdV
1, 2, 3, 4 1, 3, 6, 10
(caller) (prefix sum)
1, 2, 3, 4
24. 24
struct Point {
x: u32,
y: u32
}
!
fn area(ul: Point, lr: Point) -> u32 {
(lr.x - ul.x) * (lr.y - ul.y)
}
!
fn main() {
let origin = Point { x: 0, y: 0 };
let unit = Point { x: 1, y: 1 };
let here = Point { x: 5, y: 6 };
println!(“{:?}”, area(origin, unit));
println!(“{:?}”, area(origin, here));
}
Declare a struct
type Point with two
fields, x and y.
// 1
// ?
http://is.gd/5dDnaH
32-bit unsigned integer
26. 26
Default: Type cannot be copied.
Values move from place to place.
Example: File descriptor.
!
Clone: Type is expensive to copy,
so make it explicit by calling clone().
Example: Vector, hashtable.!
!
Copy: Type is implicitly copied
whenever it is referenced.
Example: u32, i32, Point
30. 30
fn sum(v: Vec<i32>) -> i32 {
let mut s = 0;
for i in 0 .. v.len() {
s += v[i];
}
s
}
!
fn main() {
let v = vec![1, 2, 3];
println!(“{:?}”, sum(v));
}
Take ownership
of a Vec<i32>
Give ownership
31. 31
fn sum(v: &Vec<i32>) -> i32 {
let mut s = 0;
for i in 0 .. v.len() {
s += v[i];
}
s
}
!
fn main() {
let v = vec![1, 2, 3];
println!(“{:?}”, sum(&v));
}
Borrow!
Vec<i32>
Lend the vector
http://is.gd/aHalet
32. 32
fn prefix_sum(v: &mut Vec<i32>) {
let mut s = 0;
for i in 0 .. v.len() {
s += v[i];
v[i] = s;
}
}
!
fn main() {
let mut v = vec![1, 2, 3];
prefix_sum(&mut v);
println!("{:?}", v);
}
Mutable borrow
Mutable loan
http://is.gd/jvKmF2
33. fn example() {
let mut names = Vec::new();
names.push(..);
names.push(..);
let name = &names[1];
names.push(..);
print(name);
}
names
data
length
capacity
“brson”
“pcwalton”
name
“brson”
“pcwalton”
“acrichto”
Sharing: more than
one pointer to same
memory.
Dangling pointer: pointer
to freed memory.
Mutating the vector
freed old contents.
33
34. Rust solution
34
Compile-time read-write-lock:!
!
Creating a shared reference to X “read locks” X.
- Other readers OK.
- No writers.
- Lock lasts until reference goes out of scope.
!
Creating a mutable reference to X “writes locks” X.
- No other readers or writers.
- Lock lasts until reference goes out of scope.
Never have a reader/writer at same time.
35. fn example() {
let mut names = Vec::new();
names.push(“brson”);
names.push(“pcwalton”);
let name = &names[1];
names.push(“acrichto”);
println!(“{:?}”, name);
}
Borrow “locks”
`names` until `name`
goes out of scopeError: cannot mutate
`names` while borrowed
35
http://is.gd/jeKW1E
36. Outside of borrow scope — OK.
Scope of borrow
in this case covers
only the loop body.
36
http://is.gd/thMY5N
fn main() {
let mut names = Vec::new();
names.push("brson");
names.push("pcwalton");
for i in 0 .. names.len() {
let name = &names[i];
names.push("acrichto");
println!("{:?}", name);
}
names.push("acrichto");
}
37. Rust reasons about scopes
37
fn main() {
let mut names = Vec::new();
names.push("brson");
names.push("pcwalton");
for i in 0 .. names.len() {
let name = &names[i];
println!("{:?}", name);
names.push("acrichto");
}
names.push("acrichto");
}
Even though reference is not used,
it is still in scope for the entire block..
http://is.gd/pLE8bb
51. For loops and slices
51
for x in &v {
// x is an &i32
}
let v: Vec<i32> = vec![1, 2, 3, 4];
for x in &mut v {
// x is an &mut i32
}
for x in v {
// x is an i32
} // v is consumed after loop
for converts its argument into an iterator
using the IntoIterator trait
54. Cargo
54
> cargo new my_project
> cargo new —-bin my_project
> cd my_project
> emacs
Create a template for a new project:
Edit your project:
> cargo build [—-release]
> cargo test
Build and test your project:
http://doc.crates.io/guide.html
57. Often used to make
a mod test for unit tests,
or for demonstations.
Inline modules
57
mod data {
mod point {
..
}
!
mod shape {
..
}
}
!
mod code {
lib.rs/main.rs Exactly the same as
creating a separate file.
59. Privacy
59
Privacy is the default, use pub to override.
pub struct Point {
pub x: f32,
pub y: f32,
}
impl Point {
pub fn m(&self);
}
pub enum Shape {
…
}
pub mod child;
Private means: code in this module or a descendant.
60. Where to learn more
60
doc.rust-lang.org/book
users.rust-lang.org / IRC / Stackoverflow
doc.rust-lang.org/std