SlideShare ist ein Scribd-Unternehmen logo
1 von 478
Downloaden Sie, um offline zu lesen
1
Hack without fear!
Nicholas Matsakis
2
Systems programming without the hassle
2
Systems programming without the hassle
crashes
heisenbugs
fear
2
Systems programming without the hassle
crashes
heisenbugs
fear
Parallel!
// sums all the positive values in `v`
fn sum_pos(v: &[i32]) -> i32 {
let mut sum = 0;
for i in v.iter().filter(|i| **i > 0) {
sum += *i;
}
sum
}
High-level coding
3
// sums all the positive values in `v`
fn sum_pos(v: &[i32]) -> i32 {
let mut sum = 0;
for i in v.iter().filter(|i| **i > 0) {
sum += *i;
}
sum
}
High-level coding
3
Iterators.
Closures.
Assembly code
4
leaq (%rdi,%rsi,4), %rcx
xorl %eax, %eax
jmp .LBB5_1
.LBB5_3:
addl %edx, %eax
.align 16, 0x90
.LBB5_1:
cmpq %rdi, %rcx
je .LBB5_4
movl (%rdi), %edx
addq $4, %rdi
testl %edx, %edx
jle .LBB5_1
jmp .LBB5_3
.LBB5_4:
retq
fn foo(v: &[i32]) -> i32 {
v.iter()
.filter(|i| **i > 0)
.map(|i| *i)
.sum()
}
Higher-level coding
5

generates the same assembly code.
Safe
6
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
}
Safe
6
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
}
Might free
underlying buffer.
Safe
6
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.
fn parallel_qsort(vec: &mut [int]) {
if vec.len() <= 1 { return; }
let pivot = vec[random(vec.len())];
let mid = vec.partition(vec, pivot);
let (less, greater) = vec.split_at_mut(mid);
rayon::join(
|| parallel_qsort(less),
|| parallel_qsort(greater)
);
}
Parallel
7Caveat: shameless plug for third-party package of mine.
fn parallel_qsort(vec: &mut [int]) {
if vec.len() <= 1 { return; }
let pivot = vec[random(vec.len())];
let mid = vec.partition(vec, pivot);
let (less, greater) = vec.split_at_mut(mid);
rayon::join(
|| parallel_qsort(less),
|| parallel_qsort(greater)
);
}
Parallel
7
Sort left and right
in parallel.Caveat: shameless plug for third-party package of mine.
fn parallel_qsort(vec: &mut [int]) {
if vec.len() <= 1 { return; }
let pivot = vec[random(vec.len())];
let mid = vec.partition(vec, pivot);
let (less, greater) = vec.split_at_mut(mid);
rayon::join(
|| parallel_qsort(less),
|| parallel_qsort(less)
);
}
Parallel
 and safe
8
Data race.
fn parallel_qsort(vec: &mut [int]) {
if vec.len() <= 1 { return; }
let pivot = vec[random(vec.len())];
let mid = vec.partition(vec, pivot);
let (less, greater) = vec.split_at_mut(mid);
rayon::join(
|| parallel_qsort(less),
|| parallel_qsort(less)
);
}
Parallel
 and safe
8
error: closure requires unique access to `less`
but it is already borrowed
|| parallel_qsort(less)
^~~~~~~~~~~~~~~~~~~~~~~
Data race.
Open and welcoming
Rust has been open source from the beginning.
!
Open governance model based on public RFCs.
!
We have an active, amazing community.
❀
9
The Plan
10
1. Hello, world!
2. Structs and such.
3. Threads.
11
Hello, world!
Hello, world!
12
smallcultfollowing.com/20151209/
!
Example “Hello World”
fn main() {
println!(“Hello, world!”);
}
Ownership!
!
n. The act, state, or right of possessing something.
13
Borrow!
!
v. To receive something with the promise of returning it.
Ownership/Borrowing
Memory
safety
Data-race
freedom
No need for
a runtime
14
Ownership/Borrowing
Memory
safety
Data-race
freedom
No need for
a runtime
C++
14
Ownership/Borrowing
Memory
safety
Data-race
freedom
No need for
a runtime
GCC++
14
Ownership
15
Ownership
15
fn main() {
let name = format!(“
”);
helper(name);
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Ownership 16
fn main() {
let name = format!(“
”);
helper(name);
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Ownership 16
fn main() {
let name = format!(“
”);
helper(name);
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Ownership
Take ownership
of a String
16
fn main() {
let name = format!(“
”);
helper(name);
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Ownership 16
fn main() {
let name = format!(“
”);
helper(name);
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Ownership 16
fn main() {
let name = format!(“
”);
helper(name);
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Ownership 16
fn main() {
let name = format!(“
”);
helper(name);
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Ownership 16
fn main() {
let name = format!(“
”);
helper(name);
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Ownership 16
fn main() {
let name = format!(“
”);
helper(name);
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Ownership 16
fn main() {
let name = format!(“
”);
helper(name);
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Ownership 16
Error: use of moved value: `name`
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java
Take reference
to Vector
17
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
new Thread(
);
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
new Thread(
);
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
new Thread(
);
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
new Thread(
);
void main() {
Vector name = 
;
helper(name);
helper(name);
}
void helper(Vector name) {


}
!
!
!
“Ownership” in Java 17
new Thread(
);
Clone
18
fn main() {
let name = format!(“
”);
helper(name.clone());
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Clone
18
fn main() {
let name = format!(“
”);
helper(name.clone());
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Clone
18
fn main() {
let name = format!(“
”);
helper(name.clone());
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Copy the String
Clone
18
fn main() {
let name = format!(“
”);
helper(name.clone());
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Clone
18
fn main() {
let name = format!(“
”);
helper(name.clone());
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Clone
18
fn main() {
let name = format!(“
”);
helper(name.clone());
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Clone
18
fn main() {
let name = format!(“
”);
helper(name.clone());
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Clone
18
fn main() {
let name = format!(“
”);
helper(name.clone());
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Clone
18
fn main() {
let name = format!(“
”);
helper(name.clone());
helper(name);
}
fn helper(name: String) {
println!(..);
}
!
!
!
Copy (auto-Clone)
19
fn main() {
let name = 22;
helper(name);
helper(name);
}
fn helper(name: i32) {
println!(..);
}
!
!
!
Copy (auto-Clone)
19
fn main() {
let name = 22;
helper(name);
helper(name);
}
fn helper(name: i32) {
println!(..);
}
!
!
!
i32 is a Copy type
Copy (auto-Clone)
19
fn main() {
let name = 22;
helper(name);
helper(name);
}
fn helper(name: i32) {
println!(..);
}
!
!
!
i32 is a Copy type
Copy (auto-Clone)
19
fn main() {
let name = 22;
helper(name);
helper(name);
}
fn helper(name: i32) {
println!(..);
}
!
!
!
i32 is a Copy type
Copy (auto-Clone)
19
fn main() {
let name = 22;
helper(name);
helper(name);
}
fn helper(name: i32) {
println!(..);
}
!
!
!
i32 is a Copy type
Copy (auto-Clone)
19
fn main() {
let name = 22;
helper(name);
helper(name);
}
fn helper(name: i32) {
println!(..);
}
!
!
!
i32 is a Copy type
20
Non-copyable: Values move from place to place.
Examples: File descriptor, database handle.
!
Clone: Run custom code to make a copy.
Examples: String, Vector!
!
Copy: Type is implicitly copied when referenced.
Examples: u32, i32, (f32, i32).
Exercise: ownership
21
http://smallcultfollowing.com/20151209
Cheat sheet:
fn helper(name: String) // takes ownership
!
string.clone() // clone the string
http://doc.rust-lang.org/std
Borrowing
22
Borrowing
22
Borrowing
22
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow 23
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow 23
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow 23
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow
Take a reference
to a String
23
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow
Take a reference
to a String
23
Lend the string
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow
Take a reference
to a String
23
Lend the string
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow
Take a reference
to a String
23
Lend the string
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow 23
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow 23
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow 23
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow 23
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow 23
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow 23
fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
Shared borrow 23
Shared == Immutable
24
fn helper(name: &String) {
println!(“{}”, name);
}
fn helper(name: &String) {
name.push_str(“foo”);
}
Shared == Immutable
24
fn helper(name: &String) {
println!(“{}”, name);
}
fn helper(name: &String) {
name.push_str(“foo”);
}
OK. Just reads.
Shared == Immutable
24
fn helper(name: &String) {
println!(“{}”, name);
}
fn helper(name: &String) {
name.push_str(“foo”);
}
OK. Just reads.
Error. Writes.
Shared == Immutable
24
fn helper(name: &String) {
println!(“{}”, name);
}
fn helper(name: &String) {
name.push_str(“foo”);
}
OK. Just reads.
Error. Writes.
error: cannot borrow immutable borrowed content `*name`
as mutable
name.push_str(“s”);
^~~~
Shared == Immutable
24
fn helper(name: &String) {
println!(“{}”, name);
}
fn helper(name: &String) {
name.push_str(“foo”);
}
OK. Just reads.
Error. Writes.
* Actually: mutation only in controlled circumstances.
*
error: cannot borrow immutable borrowed content `*name`
as mutable
name.push_str(“s”);
^~~~
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow
Take a mutable
reference to a String
25
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow
Take a mutable
reference to a String
25
Lend the string
mutably
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow
Take a mutable
reference to a String
25
Lend the string
mutably
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow
Take a mutable
reference to a String
25
Lend the string
mutably
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
Mutate string
in place
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
Prints the
updated string.
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
fn update(name: &mut String) {
name.push_str(“
”);
}
!
!
!
fn main() {
let mut name = 
;
update(&mut name);
println!(“{}”, name);
}
Mutable borrow 25
Play time
26http://is.gd/no0tTH
.capacity: 

.len: 10
fn helper(name: &String) {
println!(..);
}
!
!
!
27
fn main()
name.data
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
‘R’ ‘u’ 
 ‘n’ ‘s’
.capacity: 

.len: 10
fn helper(name: &String) {
println!(..);
}
!
!
!
27
fn main()
name.data
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
‘R’ ‘u’ 
 ‘n’ ‘s’
.capacity: 

.len: 10
fn helper(name: &String) {
println!(..);
}
!
!
!
27
fn main()
name.data
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
‘R’ ‘u’ 
 ‘n’ ‘s’
.capacity: 

.len: 10
fn helper(name: &String) {
println!(..);
}
!
!
!
27
fn main()
name.data
fn helper()
name
fn main() {
let name = format!(“
”);
helper(&name);
helper(&name);
}
String owned by
somebody else
up the stack.
‘R’ ‘u’ 
 ‘n’ ‘s’
.capacity: 

.len: 10
fn helper(name: &str) {
!
}
28
fn main()
name.data
fn helper()
name.data
fn main() {
let name = format!(“
”);
helper(&name[1..9]);
helper(&name);
}
.len: 8
‘R’ ‘u’ 
 ‘n’ ‘s’
“ustacean”
.capacity: 

.len: 10
fn helper(name: &str) {
!
}
28
fn main()
name.data
fn helper()
name.data
fn main() {
let name = format!(“
”);
helper(&name[1..9]);
helper(&name);
}
.len: 8
‘R’ ‘u’ 
 ‘n’ ‘s’
“ustacean”
.capacity: 

.len: 10
fn helper(name: &str) {
!
}
28
fn main()
name.data
fn helper()
name.data
fn main() {
let name = format!(“
”);
helper(&name[1..9]);
helper(&name);
}
.len: 8
‘R’ ‘u’ 
 ‘n’ ‘s’
“ustacean”
.capacity: 

.len: 10
fn helper(name: &str) {
!
}
28
fn main()
name.data
fn helper()
name.data
fn main() {
let name = format!(“
”);
helper(&name[1..9]);
helper(&name);
}
.len: 8
‘R’ ‘u’ 
 ‘n’ ‘s’
“ustacean”
.capacity: 

.len: 10
fn helper(name: &str) {
!
}
28
fn main()
name.data
fn helper()
name.data
fn main() {
let name = format!(“
”);
helper(&name[1..9]);
helper(&name);
}
.len: 8
‘R’ ‘u’ 
 ‘n’ ‘s’
“ustacean”
Subslice of a string
owned up the stack
.capacity: 

.len: 10
fn helper(name: &str) {
!
}
28
fn main()
name.data
fn helper()
name.data
fn main() {
let name = format!(“
”);
helper(&name[1..9]);
helper(&name);
}
.len: 8
‘R’ ‘u’ 
 ‘n’ ‘s’
“ustacean”
.capacity: 

.len: 10
fn helper(name: &str) {
!
}
28
fn main()
name.data
fn helper()
name.data
fn main() {
let name = format!(“
”);
helper(&name[1..9]);
helper(&name);
}
.len: 8
‘R’ ‘u’ 
 ‘n’ ‘s’
“ustacean”
helper(&name[1..]);
.capacity: 

.len: 10
fn helper(name: &str) {
!
}
28
fn main()
name.data
fn helper()
name.data
fn main() {
let name = format!(“
”);
helper(&name[1..9]);
helper(&name);
}
.len: 8
‘R’ ‘u’ 
 ‘n’ ‘s’
“ustacean”
helper(&name[1..]);
“stacean”
7
.capacity: 

.len: 10
fn helper(name: &str) {
!
}
28
fn main()
name.data
fn helper()
name.data
fn main() {
let name = format!(“
”);
helper(&name[1..9]);
helper(&name);
}
.len: 8
‘R’ ‘u’ 
 ‘n’ ‘s’
“ustacean”
helper(&name[1..]);
“stacean”
7
.capacity: 

.len: 10
fn helper(name: &str) {
!
}
28
fn main()
name.data
fn helper()
name.data
fn main() {
let name = format!(“
”);
helper(&name[1..9]);
helper(&name);
}
.len: 8
‘R’ ‘u’ 
 ‘n’ ‘s’
“ustacean”
helper(&name[1..]);
“stacean”
7
.capacity: 

.len: 10
fn helper(name: &str) {
!
}
28
fn main()
name.data
fn helper()
name.data
fn main() {
let name = format!(“
”);
helper(&name[1..9]);
helper(&name);
}
.len: 8
‘R’ ‘u’ 
 ‘n’ ‘s’
“ustacean”
helper(&name[1..]);
“stacean”
7
data
len
data
len
String
data
len
capacity
String
data
len
capacity
‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’
29
“Rustaceans”: &str
format!(“Rustaceans”): String

Rustaceans

data
len
data
len
String
data
len
capacity
String
data
len
capacity
‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’
29
“Rustaceans”: &str
format!(“Rustaceans”): String

Rustaceans

data
len
data
len
String
data
len
capacity
String
data
len
capacity
‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’
29
“Rustaceans”: &str
format!(“Rustaceans”): String

Rustaceans

data
len
data
len
String
data
len
capacity
String
data
len
capacity
‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’
29
“Rustaceans”: &str
format!(“Rustaceans”): String

Rustaceans

data
len
data
len
String
data
len
capacity
String
data
len
capacity
‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’
29
“Rustaceans”: &str
format!(“Rustaceans”): String

Rustaceans

data
len
data
len
String
data
len
capacity
String
data
len
capacity
‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’
29
“Rustaceans”: &str
format!(“Rustaceans”): String

Rustaceans

&’static str
data
len
data
len
String
data
len
capacity
String
data
len
capacity
‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’
29
“Rustaceans”: &str
format!(“Rustaceans”): String

Rustaceans

&’static str
Whither Safety?
30https://www.ïŹ‚ickr.com/photos/langtind/2217639550/in/photostream/
GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size ïŹts all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — conïŹned to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size ïŹts all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — conïŹned to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size ïŹts all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — conïŹned to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size ïŹts all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — conïŹned to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size ïŹts all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — conïŹned to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size ïŹts all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — conïŹned to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size ïŹts all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — conïŹned to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size ïŹts all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — conïŹned to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size ïŹts all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — conïŹned to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size ïŹts all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — conïŹned to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size ïŹts all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — conïŹned to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
.capacity: 

.len: 10
name.data ‘R’ ‘u’ 
 ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
.capacity: 

.len: 10
name.data ‘R’ ‘u’ 
 ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
.capacity: 

.len: 10
name.data ‘R’ ‘u’ 
 ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
.capacity: 

.len: 10
name.data ‘R’ ‘u’ 
 ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
.capacity: 

.len: 10
name.data ‘R’ ‘u’ 
 ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
.capacity: 

.len: 10
name.data ‘R’ ‘u’ 
 ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
.capacity: 

.len: 10
name.data ‘R’ ‘u’ 
 ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
.capacity: 

.len: 10
name.data ‘R’ ‘u’ 
 ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
.capacity: 

.len: 10
name.data ‘R’ ‘u’ 
 ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
.capacity: 

.len: 10
name.data ‘R’ ‘u’ 
 ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
Dangling
reference!
.capacity: 

.len: 10
name.data ‘R’ ‘u’ 
 ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
r
Dangling
reference!
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
33http://is.gd/HJyO7A
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
33http://is.gd/HJyO7A
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
33
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
33
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
33
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
33
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
33
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
33
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
33
‘l
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
33
‘l
Lifetime: span of code where reference is used.
Scope of data being borrowed (here, `name`)
compared against
http://is.gd/HJyO7A
‘s
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
33
‘l
Lifetime: span of code where reference is used.
Scope of data being borrowed (here, `name`)
compared against
http://is.gd/HJyO7A
‘s
fn main() {
let r;
{
let name = format!(“
”);
r = &name;
}
println!(“{}”, r);
}
33
‘l
Lifetime: span of code where reference is used.
Scope of data being borrowed (here, `name`)
compared against
http://is.gd/HJyO7A
error: `name` does not live long enough
r = &name;
^~~~
34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
Might escape
the function!
34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
Might escape
the function!
error: the type `[
]` does not fulfill the required lifetime
thread::spawn(move || {
^~~~~~~~~~~~~
note: type must outlive the static lifetime
34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
error: the type `[
]` does not fulfill the required lifetime
thread::spawn(move || {
^~~~~~~~~~~~~
note: type must outlive the static lifetime
34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
error: the type `[
]` does not fulfill the required lifetime
thread::spawn(move || {
^~~~~~~~~~~~~
note: type must outlive the static lifetime
34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
error: the type `[
]` does not fulfill the required lifetime
thread::spawn(move || {
^~~~~~~~~~~~~
note: type must outlive the static lifetime
34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
error: the type `[
]` does not fulfill the required lifetime
thread::spawn(move || {
^~~~~~~~~~~~~
note: type must outlive the static lifetime
However: see crossbeam,
simple_parallel, etc on
crates.io
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ 
 ‘n’
String
data
len
capacity
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ 
 ‘n’
String
data
len
capacity
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ 
 ‘n’
String
data
len
capacity
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ 
 ‘n’
String
data
len
capacity
data
len
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ 
 ‘n’
String
data
len
capacity
data
len
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ 
 ‘n’
String
data
len
capacity
data
len
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ 
 ‘n’
String
data
len
capacity
‘R’ ‘u’ 
 ‘n’
data
len
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ 
 ‘n’
String
data
len
capacity
‘R’ ‘u’ 
 ‘n’
data
len
‘s’
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
String
data
len
capacity
‘R’ ‘u’ 
 ‘n’
data
len
‘R’ ‘u’ 
 ‘n’
‘s’
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
String
data
len
capacity
‘R’ ‘u’ 
 ‘n’
data
len
‘R’ ‘u’ 
 ‘n’
‘s’
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
String
data
len
capacity
‘R’ ‘u’ 
 ‘n’
data
len
‘R’ ‘u’ 
 ‘n’
‘s’
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
String
data
len
capacity
‘R’ ‘u’ 
 ‘n’
data
len
‘R’ ‘u’ 
 ‘n’
‘s’
Dangling
reference!
Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
String
data
len
capacity
‘R’ ‘u’ 
 ‘n’
data
len
‘R’ ‘u’ 
 ‘n’
‘s’
Dangling
reference!
Rust solution
36
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.
Dangers of mutation
37
fn main() {
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
http://is.gd/MCPVWg
Dangers of mutation
37
fn main() {
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
http://is.gd/MCPVWg
Dangers of mutation
37
fn main() {
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
Borrow “locks”
`buffer` until `slice`
goes out of scope
http://is.gd/MCPVWg
Dangers of mutation
37
fn main() {
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
Borrow “locks”
`buffer` until `slice`
goes out of scope
http://is.gd/MCPVWg
Dangers of mutation
37
fn main() {
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
Borrow “locks”
`buffer` until `slice`
goes out of scope
error: cannot borrow `buffer` as mutable
because it is also borrowed as immutable
buffer.push_str(“s”);
^~~~~~
http://is.gd/MCPVWg
Dangers of mutation
37
fn main() {
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
Borrow “locks”
`buffer` until `slice`
goes out of scope
error: cannot borrow `buffer` as mutable
because it is also borrowed as immutable
buffer.push_str(“s”);
^~~~~~
http://is.gd/MCPVWg
fn main() {
let mut buffer: String = format!(“Rustacean”);
for i in 0 .. buffer.len() {
let slice = &buffer[i..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
buffer.push_str(“s”);
}
38
fn main() {
let mut buffer: String = format!(“Rustacean”);
for i in 0 .. buffer.len() {
let slice = &buffer[i..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
buffer.push_str(“s”);
}
38
Borrow “locks”
`buffer` until `slice`
goes out of scope
fn main() {
let mut buffer: String = format!(“Rustacean”);
for i in 0 .. buffer.len() {
let slice = &buffer[i..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
buffer.push_str(“s”);
}
38
Borrow “locks”
`buffer` until `slice`
goes out of scope
fn main() {
let mut buffer: String = format!(“Rustacean”);
for i in 0 .. buffer.len() {
let slice = &buffer[i..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
buffer.push_str(“s”);
}
38
Borrow “locks”
`buffer` until `slice`
goes out of scope
fn main() {
let mut buffer: String = format!(“Rustacean”);
for i in 0 .. buffer.len() {
let slice = &buffer[i..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
buffer.push_str(“s”);
}
38
Borrow “locks”
`buffer` until `slice`
goes out of scope
OK: `buffer` is not borrowed here
Exercise: borrowing
39
http://smallcultfollowing.com/20151209
Cheat sheet:
&String // type of shared reference
&mut String // type of mutable reference
&str // type of string slice
!
&name // shared borrow
&mut name // mutable borrow
&name[x..y] // slice expression
http://doc.rust-lang.org/std
40
Structs and such
41
Shop till you drop!
By QuentinUK (Own work), via Wikimedia Commons
Declaring a structure
42
struct Store {
name: String,
prices: Vec<Item>,
}
Declaring a structure
42
struct Store {
name: String,
prices: Vec<Item>,
}
Declaring a structure
42
struct Store {
name: String,
prices: Vec<Item>,
}
Declaring a structure
42
struct Store {
name: String,
prices: Vec<Item>,
}
Declaring a structure
42
struct Store {
name: String,
prices: Vec<Item>,
}
Declaring a structure
42
struct Store {
name: String,
prices: Vec<Item>,
}
Declaring a structure
42
struct Store {
name: String,
prices: Vec<Item>,
}
Declaring a structure
42
struct Store {
name: String,
prices: Vec<Item>,
}
Declaring a structure
42
struct Store {
name: String,
prices: Vec<Item>,
}
Declaring a structure
42
struct Store {
name: String,
prices: Vec<Item>,
}
name
prices
Declaring a structure
42
struct Store {
name: String,
prices: Vec<Item>,
}
name
prices
.length
.data
.capacity
.length
.data
.capacity
Declaring a structure
42
struct Store {
name: String,
prices: Vec<Item>,
}
Item
name
prices
‘R’ ‘u’ 
 ‘n’
Item
Item
.length
.data
.capacity
.length
.data
.capacity
Declaring a structure
42
struct Store {
name: String,
prices: Vec<Item>,
}
Item
name
prices
‘R’ ‘u’ 
 ‘n’
Item
Item
.length
.data
.capacity
.length
.data
.capacity
43
struct Item {
name: &’static str,
price: f32,
}
Other fundamental types
f32
f64
!
!
i8
i16
i32
i64
isize
u8
u16
u32
u64
usize
&str
&[T]
!
!
ïŹ‚oats signed unsigned slices
43
struct Item {
name: &’static str,
price: f32,
}
Other fundamental types
f32
f64
!
!
i8
i16
i32
i64
isize
u8
u16
u32
u64
usize
&str
&[T]
!
!
ïŹ‚oats signed unsigned slices
43
struct Item {
name: &’static str,
price: f32,
}
Other fundamental types
f32
f64
!
!
i8
i16
i32
i64
isize
u8
u16
u32
u64
usize
&str
&[T]
!
!
ïŹ‚oats signed unsigned slices
43
struct Item {
name: &’static str,
price: f32,
}
Other fundamental types
f32
f64
!
!
i8
i16
i32
i64
isize
u8
u16
u32
u64
usize
&str
&[T]
!
!
ïŹ‚oats signed unsigned slices
43
struct Item {
name: &’static str,
price: f32,
}
Other fundamental types
f32
f64
!
!
i8
i16
i32
i64
isize
u8
u16
u32
u64
usize
&str
&[T]
!
!
ïŹ‚oats signed unsigned slices
43
struct Item {
name: &’static str,
price: f32,
}
Other fundamental types
f32
f64
!
!
i8
i16
i32
i64
isize
u8
u16
u32
u64
usize
&str
&[T]
!
!
ïŹ‚oats signed unsigned slices
43
struct Item {
name: &’static str,
price: f32,
}
Other fundamental types
f32
f64
!
!
i8
i16
i32
i64
isize
u8
u16
u32
u64
usize
&str
&[T]
!
!
ïŹ‚oats signed unsigned slices
43
struct Item {
name: &’static str,
price: f32,
}
Other fundamental types
f32
f64
!
!
i8
i16
i32
i64
isize
u8
u16
u32
u64
usize
&str
&[T]
!
!
ïŹ‚oats signed unsigned slices
43
struct Item {
name: &’static str,
price: f32,
}
Other fundamental types
f32
f64
!
!
i8
i16
i32
i64
isize
u8
u16
u32
u64
usize
&str
&[T]
!
!
ïŹ‚oats signed unsigned slices
43
struct Item {
name: &’static str,
price: f32,
}
Other fundamental types
f32
f64
!
!
i8
i16
i32
i64
isize
u8
u16
u32
u64
usize
&str
&[T]
!
!
ïŹ‚oats signed unsigned slices
43
struct Item {
name: &’static str,
price: f32,
}
Other fundamental types
f32
f64
!
!
i8
i16
i32
i64
isize
u8
u16
u32
u64
usize
&str
&[T]
!
!
ïŹ‚oats signed unsigned slices
43
struct Item {
name: &’static str,
price: f32,
}
Other fundamental types
f32
f64
!
!
i8
i16
i32
i64
isize
u8
u16
u32
u64
usize
&str
&[T]
!
!
ïŹ‚oats signed unsigned slices
43
struct Item {
name: &’static str,
price: f32,
}
Other fundamental types
f32
f64
!
!
i8
i16
i32
i64
isize
u8
u16
u32
u64
usize
&str
&[T]
!
!
ïŹ‚oats signed unsigned slices
Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {

 // see upcoming slide
}
}
Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {

 // see upcoming slide
}
}
Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {

 // see upcoming slide
}
}
Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {

 // see upcoming slide
}
}
store.add_item(
); // must be let mut
store.price(
); // let OR let mut
Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {

 // see upcoming slide
}
}
store.add_item(
); // must be let mut
store.price(
); // let OR let mut
Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {

 // see upcoming slide
}
}
store.add_item(
); // must be let mut
store.price(
); // let OR let mut
itself an &mut method
Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {

 // see upcoming slide
}
}
store.add_item(
); // must be let mut
store.price(
); // let OR let mut
Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {

 // see upcoming slide
}
}
store.add_item(
); // must be let mut
store.price(
); // let OR let mut
Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {

 // see upcoming slide
}
}
store.add_item(
); // must be let mut
store.price(
); // let OR let mut
Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {

 // see upcoming slide
}
}
store.add_item(
); // must be let mut
store.price(
); // let OR let mut
Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {

 // see upcoming slide
}
}
store.add_item(
); // must be let mut
store.price(
); // let OR let mut
Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {

 // see upcoming slide
}
}
store.add_item(
); // must be let mut
store.price(
); // let OR let mut
Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
Return is optional
46
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
Store {
name: name,
items: vec![],
}
}
}
Return is optional
46
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
Store {
name: name,
items: vec![],
}
}
}
No `;` on last expression:
“return this value”
Options and Enums
47
enum Option<T> {
Some(T),
None
}
fn main() {
let v: Option<i32> = Some(22);
match v {
Some(x) => println!(“v = {}”, x),
None => println!(“v = None”),
}
println!(“v = {}”, v.unwrap()); // risky
}
http://is.gd/Gfum32
Options and Enums
47
enum Option<T> {
Some(T),
None
}
fn main() {
let v: Option<i32> = Some(22);
match v {
Some(x) => println!(“v = {}”, x),
None => println!(“v = None”),
}
println!(“v = {}”, v.unwrap()); // risky
}
http://is.gd/Gfum32
Options and Enums
47
enum Option<T> {
Some(T),
None
}
fn main() {
let v: Option<i32> = Some(22);
match v {
Some(x) => println!(“v = {}”, x),
None => println!(“v = None”),
}
println!(“v = {}”, v.unwrap()); // risky
}
http://is.gd/Gfum32
Options and Enums
47
enum Option<T> {
Some(T),
None
}
fn main() {
let v: Option<i32> = Some(22);
match v {
Some(x) => println!(“v = {}”, x),
None => println!(“v = None”),
}
println!(“v = {}”, v.unwrap()); // risky
}
http://is.gd/Gfum32
Options and Enums
47
enum Option<T> {
Some(T),
None
}
fn main() {
let v: Option<i32> = Some(22);
match v {
Some(x) => println!(“v = {}”, x),
None => println!(“v = None”),
}
println!(“v = {}”, v.unwrap()); // risky
}
http://is.gd/Gfum32
Options and Enums
47
enum Option<T> {
Some(T),
None
}
fn main() {
let v: Option<i32> = Some(22);
match v {
Some(x) => println!(“v = {}”, x),
None => println!(“v = None”),
}
println!(“v = {}”, v.unwrap()); // risky
}
http://is.gd/Gfum32
Options and Enums
47
enum Option<T> {
Some(T),
None
}
fn main() {
let v: Option<i32> = Some(22);
match v {
Some(x) => println!(“v = {}”, x),
None => println!(“v = None”),
}
println!(“v = {}”, v.unwrap()); // risky
}
http://is.gd/Gfum32
Options and Enums
47
enum Option<T> {
Some(T),
None
}
fn main() {
let v: Option<i32> = Some(22);
match v {
Some(x) => println!(“v = {}”, x),
None => println!(“v = None”),
}
println!(“v = {}”, v.unwrap()); // risky
}
http://is.gd/Gfum32
Options and Enums
47
enum Option<T> {
Some(T),
None
}
fn main() {
let v: Option<i32> = Some(22);
match v {
Some(x) => println!(“v = {}”, x),
None => println!(“v = None”),
}
println!(“v = {}”, v.unwrap()); // risky
}
http://is.gd/Gfum32
Options and Enums
47
enum Option<T> {
Some(T),
None
}
fn main() {
let v: Option<i32> = Some(22);
match v {
Some(x) => println!(“v = {}”, x),
None => println!(“v = None”),
}
println!(“v = {}”, v.unwrap()); // risky
}
http://is.gd/Gfum32
Options and Enums
47
enum Option<T> {
Some(T),
None
}
fn main() {
let v: Option<i32> = Some(22);
match v {
Some(x) => println!(“v = {}”, x),
None => println!(“v = None”),
}
println!(“v = {}”, v.unwrap()); // risky
}
http://is.gd/Gfum32
For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
Vec<String>
For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
String
Vec<String>
For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Beta”
“Gamma”
v: s:
For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Beta”
“Gamma”
v: s:
For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Gamma”
v: s:
For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
&Vec<String>
For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
&String
&Vec<String>
For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
s:
For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
s:
For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
s:
For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
s:
&mut Vec<String>
&mut String
For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
s:
Exercise: structs
50
http://smallcultfollowing.com/20151209
Implement
fn total_price(..)
Cheat sheet:
for s in v { 
 }
for s in &v { 
 }
let mut some_var = 0.0;
println!(“{:?}”, s);
some_var += x;
while 
 { 
 }
http://doc.rust-lang.org/std
51
Threading
Multiparadigm
52
Multiparadigm
Multiparadigm
52
Multiparadigm
message-passing
Multiparadigm
52
Multiparadigm
mutable shared memorymessage-passing
53
53
$5.0
$25.5
$81.5
———
$112.0
53
$5.0
$25.5
$81.5
———
$112.0
$5.0
$20.5
$81.5
———
$107.0
53
$5.0
$25.5
$81.5
———
$112.0
$5.0
$20.5
$81.5
———
$107.0
$5.0
$23.5
XXX
———
XXX
53
$5.0
$25.5
$81.5
———
$112.0
$5.0
$20.5
$81.5
———
$107.0
$5.0
$23.5
XXX
———
XXX
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
55
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
55
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
55
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
55
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
Closure
takes ownership
of variables it uses.
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
Closure
takes ownership
of variables it uses.
Variables used by
this closure.
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
Closure
takes ownership
of variables it uses.
Variables used by
this closure.
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
Handle to the
thread we spawned.
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
Closure body can
produce a result,
here a (String, f32).
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
use std::thread;


let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
57
let handle = thread::spawn(
);
57
let handle = thread::spawn(
);
57
let handle = thread::spawn(
);

 // stuff in parallel
// with new thread
57
let handle = thread::spawn(
);

 // stuff in parallel
// with new thread
let (name, sum) = handle.join().unwrap();
57
let handle = thread::spawn(
);

 // stuff in parallel
// with new thread
let (name, sum) = handle.join().unwrap();
57
let handle = thread::spawn(
);

 // stuff in parallel
// with new thread
let (name, sum) = handle.join().unwrap();
Wait for thread
to ïŹnish and
get return value.
57
let handle = thread::spawn(
);

 // stuff in parallel
// with new thread
let (name, sum) = handle.join().unwrap();
Wait for thread
to ïŹnish and
get return value.
Result<(String, f32), Error>
57
let handle = thread::spawn(
);

 // stuff in parallel
// with new thread
let (name, sum) = handle.join().unwrap();
Wait for thread
to ïŹnish and
get return value.
Thread may have
panicked. Propagate.
57
let handle = thread::spawn(
);

 // stuff in parallel
// with new thread
let (name, sum) = handle.join().unwrap();
Wait for thread
to ïŹnish and
get return value.
Thread may have
panicked. Propagate.Result of thread.
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
58
let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = 
;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
59
use std::thread;


let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
59
use std::thread;


let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
Variables used by
this closure.
59
use std::thread;


let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
59
use std::thread;


let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
59
use std::thread;


let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
59
use std::thread;


let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
59
use std::thread;


let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
error: capture of moved value: `shopping_list`
let sum = store.total_price(&shopping_list);
^~~~~~~~~~~~~


help: perhaps you meant to use `clone()`?
59
use std::thread;


let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
error: capture of moved value: `shopping_list`
let sum = store.total_price(&shopping_list);
^~~~~~~~~~~~~


help: perhaps you meant to use `clone()`?
60
use std::thread;


let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
60
use std::thread;


let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
60
use std::thread;


let shopping_list = vec![
];
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
arc1
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
arc1
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
arc1
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
arc1
arc2
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
arc1
arc2
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
arc1
arc2
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
arc1
arc2
data
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
arc1
arc2
data
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
arc1
arc2
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
arc1
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
61
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let arc2 = arc1.clone();
let data = &arc1[0];
Arc => Immutable
62
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let data = &mut arc1[0];
http://is.gd/nP3Pvb
Arc => Immutable
62
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let data = &mut arc1[0];
http://is.gd/nP3Pvb
Arc => Immutable
62
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = 
;
let arc1 = Arc::new(shopping_list);
let data = &mut arc1[0];
<anon>:6:21: 6:24 error: cannot borrow immutable borrowed
content as mutable
<anon>:6 let data = &mut arc[0];
^~~
http://is.gd/nP3Pvb
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
63
use std::thread;


let shopping_list = Arc::new(vec![
]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
// exercise (in a bit): join the handles!
Channels
64
65
Joining a thread allows
thread to send one result.
What if we wanted
multiple results?
65
Joining a thread allows
thread to send one result.
What if we wanted
multiple results?
65
Joining a thread allows
thread to send one result.
What if we wanted
multiple results?
65
Joining a thread allows
thread to send one result.
What if we wanted
multiple results?
65
Joining a thread allows
thread to send one result.
What if we wanted
multiple results?
65
Joining a thread allows
thread to send one result.
What if we wanted
multiple results?
65
Joining a thread allows
thread to send one result.
What if we wanted
multiple results?
Or if we wanted
a response?
65
Joining a thread allows
thread to send one result.
What if we wanted
multiple results?
Or if we wanted
a response?
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
rx
tx
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
rx
tx
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
rx
tx
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
rx
tx
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
move || {
let m = Message::new();


tx.send(m).unwrap();
}
rx
tx
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
move || {
let m = Message::new();


tx.send(m).unwrap();
}
rx
tx
tx
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
move || {
let m = Message::new();


tx.send(m).unwrap();
}
rx
tx
tx
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
move || {
let m = Message::new();


tx.send(m).unwrap();
}
MessageMessage
rx
tx
tx
m
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
move || {
let m = Message::new();


tx.send(m).unwrap();
}
MessageMessage
rx
tx
tx
m
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
move || {
let m = Message::new();


tx.send(m).unwrap();
}
Message
Message
rx
tx
tx
m
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
move || {
let m = Message::new();


tx.send(m).unwrap();
}
Message
Message
rx
tx
tx
m
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
move || {
let m = Message::new();


tx.send(m).unwrap();
}
Message
Message
rx
tx
tx
m
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
move || {
let m = Message::new();


tx.send(m).unwrap();
}
Message
Message
rx
tx
tx
m
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
move || {
let m = Message::new();


tx.send(m).unwrap();
}
Message
Message
rx
tx
tx
m
fn parent() {
let (tx, rx) = channel();
spawn(move || {
});
let m = rx.recv().unwrap();
}
66
move || {
let m = Message::new();


tx.send(m).unwrap();
}
67
rx0
tx0
let (tx0, rx0) = channel();
let tx1 = tx0.clone();
spawn(move || /* omitted */);
let tx2 = tx0.clone();
spawn(move || /* omitted */);
67
rx0
tx0
let (tx0, rx0) = channel();
let tx1 = tx0.clone();
spawn(move || /* omitted */);
let tx2 = tx0.clone();
spawn(move || /* omitted */);
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial
Rust Mozlando Tutorial

Weitere Àhnliche Inhalte

Was ist angesagt?

Intro to Rust from Applicative / NY Meetup
Intro to Rust from Applicative / NY MeetupIntro to Rust from Applicative / NY Meetup
Intro to Rust from Applicative / NY Meetupnikomatsakis
 
Rust: Unlocking Systems Programming
Rust: Unlocking Systems ProgrammingRust: Unlocking Systems Programming
Rust: Unlocking Systems ProgrammingC4Media
 
Rust "Hot or Not" at Sioux
Rust "Hot or Not" at SiouxRust "Hot or Not" at Sioux
Rust "Hot or Not" at Siouxnikomatsakis
 
Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017 Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017 pramode_ce
 
Rust: ĐșĐŸĐŽ ĐŒĐŸĐ¶Đ”Ń‚ Đ±Ń‹Ń‚ŃŒ ĐŸĐŽĐœĐŸĐČŃ€Đ”ĐŒĐ”ĐœĐœĐŸ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœŃ‹ĐŒ Đž Đ±Ń‹ŃŃ‚Ń€Ń‹ĐŒ, ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČ
Rust: ĐșĐŸĐŽ ĐŒĐŸĐ¶Đ”Ń‚ Đ±Ń‹Ń‚ŃŒ ĐŸĐŽĐœĐŸĐČŃ€Đ”ĐŒĐ”ĐœĐœĐŸ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœŃ‹ĐŒ Đž Đ±Ń‹ŃŃ‚Ń€Ń‹ĐŒ, ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČRust: ĐșĐŸĐŽ ĐŒĐŸĐ¶Đ”Ń‚ Đ±Ń‹Ń‚ŃŒ ĐŸĐŽĐœĐŸĐČŃ€Đ”ĐŒĐ”ĐœĐœĐŸ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœŃ‹ĐŒ Đž Đ±Ń‹ŃŃ‚Ń€Ń‹ĐŒ, ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČ
Rust: ĐșĐŸĐŽ ĐŒĐŸĐ¶Đ”Ń‚ Đ±Ń‹Ń‚ŃŒ ĐŸĐŽĐœĐŸĐČŃ€Đ”ĐŒĐ”ĐœĐœĐŸ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœŃ‹ĐŒ Đž Đ±Ń‹ŃŃ‚Ń€Ń‹ĐŒ, ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČYandex
 
Ownership System in Rust
Ownership System in RustOwnership System in Rust
Ownership System in RustChih-Hsuan Kuo
 
NativeBoost
NativeBoostNativeBoost
NativeBoostESUG
 
ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČ â€” Rust — Đ»ŃƒŃ‡ŃˆĐ”, Ń‡Đ”ĐŒ C++
ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČ â€” Rust — Đ»ŃƒŃ‡ŃˆĐ”, Ń‡Đ”ĐŒ C++ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČ â€” Rust — Đ»ŃƒŃ‡ŃˆĐ”, Ń‡Đ”ĐŒ C++
ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČ â€” Rust — Đ»ŃƒŃ‡ŃˆĐ”, Ń‡Đ”ĐŒ C++Yandex
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6Solution4Future
 
Protocol handler in Gecko
Protocol handler in GeckoProtocol handler in Gecko
Protocol handler in GeckoChih-Hsuan Kuo
 
Python AsĂ­ncrono - Async Python
Python AsĂ­ncrono - Async PythonPython AsĂ­ncrono - Async Python
Python AsĂ­ncrono - Async PythonJavier AbadĂ­a
 
The Ring programming language version 1.5.3 book - Part 25 of 184
The Ring programming language version 1.5.3 book - Part 25 of 184The Ring programming language version 1.5.3 book - Part 25 of 184
The Ring programming language version 1.5.3 book - Part 25 of 184Mahmoud Samir Fayed
 
Python in 90mins
Python in 90minsPython in 90mins
Python in 90minsLarry Cai
 
C++totural file
C++totural fileC++totural file
C++totural filehalaisumit
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.UA Mobile
 
What the &~#@&lt;!? (Pointers in Rust)
What the &~#@&lt;!? (Pointers in Rust)What the &~#@&lt;!? (Pointers in Rust)
What the &~#@&lt;!? (Pointers in Rust)David Evans
 

Was ist angesagt? (20)

Intro to Rust from Applicative / NY Meetup
Intro to Rust from Applicative / NY MeetupIntro to Rust from Applicative / NY Meetup
Intro to Rust from Applicative / NY Meetup
 
Rust: Unlocking Systems Programming
Rust: Unlocking Systems ProgrammingRust: Unlocking Systems Programming
Rust: Unlocking Systems Programming
 
Rust "Hot or Not" at Sioux
Rust "Hot or Not" at SiouxRust "Hot or Not" at Sioux
Rust "Hot or Not" at Sioux
 
Why rust?
Why rust?Why rust?
Why rust?
 
Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017 Rust Workshop - NITC FOSSMEET 2017
Rust Workshop - NITC FOSSMEET 2017
 
Rust: ĐșĐŸĐŽ ĐŒĐŸĐ¶Đ”Ń‚ Đ±Ń‹Ń‚ŃŒ ĐŸĐŽĐœĐŸĐČŃ€Đ”ĐŒĐ”ĐœĐœĐŸ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœŃ‹ĐŒ Đž Đ±Ń‹ŃŃ‚Ń€Ń‹ĐŒ, ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČ
Rust: ĐșĐŸĐŽ ĐŒĐŸĐ¶Đ”Ń‚ Đ±Ń‹Ń‚ŃŒ ĐŸĐŽĐœĐŸĐČŃ€Đ”ĐŒĐ”ĐœĐœĐŸ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœŃ‹ĐŒ Đž Đ±Ń‹ŃŃ‚Ń€Ń‹ĐŒ, ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČRust: ĐșĐŸĐŽ ĐŒĐŸĐ¶Đ”Ń‚ Đ±Ń‹Ń‚ŃŒ ĐŸĐŽĐœĐŸĐČŃ€Đ”ĐŒĐ”ĐœĐœĐŸ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœŃ‹ĐŒ Đž Đ±Ń‹ŃŃ‚Ń€Ń‹ĐŒ, ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČ
Rust: ĐșĐŸĐŽ ĐŒĐŸĐ¶Đ”Ń‚ Đ±Ń‹Ń‚ŃŒ ĐŸĐŽĐœĐŸĐČŃ€Đ”ĐŒĐ”ĐœĐœĐŸ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœŃ‹ĐŒ Đž Đ±Ń‹ŃŃ‚Ń€Ń‹ĐŒ, ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČ
 
Ownership System in Rust
Ownership System in RustOwnership System in Rust
Ownership System in Rust
 
Python
PythonPython
Python
 
NativeBoost
NativeBoostNativeBoost
NativeBoost
 
ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČ â€” Rust — Đ»ŃƒŃ‡ŃˆĐ”, Ń‡Đ”ĐŒ C++
ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČ â€” Rust — Đ»ŃƒŃ‡ŃˆĐ”, Ń‡Đ”ĐŒ C++ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČ â€” Rust — Đ»ŃƒŃ‡ŃˆĐ”, Ń‡Đ”ĐŒ C++
ĐĄŃ‚Đ”ĐżĐ°Đœ ĐšĐŸĐ»ŃŒŃ†ĐŸĐČ â€” Rust — Đ»ŃƒŃ‡ŃˆĐ”, Ń‡Đ”ĐŒ C++
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6
 
Protocol handler in Gecko
Protocol handler in GeckoProtocol handler in Gecko
Protocol handler in Gecko
 
Python AsĂ­ncrono - Async Python
Python AsĂ­ncrono - Async PythonPython AsĂ­ncrono - Async Python
Python AsĂ­ncrono - Async Python
 
The Ring programming language version 1.5.3 book - Part 25 of 184
The Ring programming language version 1.5.3 book - Part 25 of 184The Ring programming language version 1.5.3 book - Part 25 of 184
The Ring programming language version 1.5.3 book - Part 25 of 184
 
Python in 90mins
Python in 90minsPython in 90mins
Python in 90mins
 
C++totural file
C++totural fileC++totural file
C++totural file
 
Rust
RustRust
Rust
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
 
C++ tutorial
C++ tutorialC++ tutorial
C++ tutorial
 
What the &~#@&lt;!? (Pointers in Rust)
What the &~#@&lt;!? (Pointers in Rust)What the &~#@&lt;!? (Pointers in Rust)
What the &~#@&lt;!? (Pointers in Rust)
 

Ähnlich wie Rust Mozlando Tutorial

Rustlabs Quick Start
Rustlabs Quick StartRustlabs Quick Start
Rustlabs Quick Startsangam biradar
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchainedEduard TomĂ s
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+ConFoo
 
Swift 5.1 Language Guide Notes.pdf
Swift 5.1 Language Guide Notes.pdfSwift 5.1 Language Guide Notes.pdf
Swift 5.1 Language Guide Notes.pdfJkPoppy
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming iiPrashant Kalkar
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecLoĂŻc Descotte
 
Kotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsKotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsFranco Lombardo
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubyJason Yeo Jie Shun
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4Emil Vladev
 
golang_getting_started.pptx
golang_getting_started.pptxgolang_getting_started.pptx
golang_getting_started.pptxGuy Komari
 
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdfModify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdfarjuncorner565
 
仕äș‹ă§äœżă†F#
仕äș‹ă§äœżă†F#仕äș‹ă§äœżă†F#
仕äș‹ă§äœżă†F#bleis tift
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Workhorse Computing
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6FITC
 
Go Programming Language (Golang)
Go Programming Language (Golang)Go Programming Language (Golang)
Go Programming Language (Golang)Ishin Vin
 
GeoGebra JavaScript CheatSheet
GeoGebra JavaScript CheatSheetGeoGebra JavaScript CheatSheet
GeoGebra JavaScript CheatSheetJose Perez
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldBTI360
 
Sharable_Java_Python.pdf
Sharable_Java_Python.pdfSharable_Java_Python.pdf
Sharable_Java_Python.pdfICADCMLTPC
 
The groovy puzzlers (as Presented at JavaOne 2014)
The groovy puzzlers (as Presented at JavaOne 2014)The groovy puzzlers (as Presented at JavaOne 2014)
The groovy puzzlers (as Presented at JavaOne 2014)GroovyPuzzlers
 

Ähnlich wie Rust Mozlando Tutorial (20)

Rustlabs Quick Start
Rustlabs Quick StartRustlabs Quick Start
Rustlabs Quick Start
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
 
Swift 5.1 Language Guide Notes.pdf
Swift 5.1 Language Guide Notes.pdfSwift 5.1 Language Guide Notes.pdf
Swift 5.1 Language Guide Notes.pdf
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
 
Kotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsKotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functions
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in Ruby
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
golang_getting_started.pptx
golang_getting_started.pptxgolang_getting_started.pptx
golang_getting_started.pptx
 
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdfModify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
 
仕äș‹ă§äœżă†F#
仕äș‹ă§äœżă†F#仕äș‹ă§äœżă†F#
仕äș‹ă§äœżă†F#
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6
 
Go Programming Language (Golang)
Go Programming Language (Golang)Go Programming Language (Golang)
Go Programming Language (Golang)
 
GeoGebra JavaScript CheatSheet
GeoGebra JavaScript CheatSheetGeoGebra JavaScript CheatSheet
GeoGebra JavaScript CheatSheet
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 World
 
Sharable_Java_Python.pdf
Sharable_Java_Python.pdfSharable_Java_Python.pdf
Sharable_Java_Python.pdf
 
The groovy puzzlers (as Presented at JavaOne 2014)
The groovy puzzlers (as Presented at JavaOne 2014)The groovy puzzlers (as Presented at JavaOne 2014)
The groovy puzzlers (as Presented at JavaOne 2014)
 

KĂŒrzlich hochgeladen

2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shardsChristopher Curtin
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencessuser9e7c64
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesKrzysztofKkol1
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonApplitools
 
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jGraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jNeo4j
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...OnePlan Solutions
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITmanoharjgpsolutions
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxRTS corp
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingShane Coughlan
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfmaor17
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesVictoriaMetrics
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slidesvaideheekore1
 

KĂŒrzlich hochgeladen (20)

2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conference
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
 
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jGraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh IT
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdf
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 Updates
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slides
 

Rust Mozlando Tutorial

  • 3. 2 Systems programming without the hassle crashes heisenbugs fear
  • 4. 2 Systems programming without the hassle crashes heisenbugs fear Parallel!
  • 5. // sums all the positive values in `v` fn sum_pos(v: &[i32]) -> i32 { let mut sum = 0; for i in v.iter().filter(|i| **i > 0) { sum += *i; } sum } High-level coding 3
  • 6. // sums all the positive values in `v` fn sum_pos(v: &[i32]) -> i32 { let mut sum = 0; for i in v.iter().filter(|i| **i > 0) { sum += *i; } sum } High-level coding 3 Iterators. Closures.
  • 7. Assembly code 4 leaq (%rdi,%rsi,4), %rcx xorl %eax, %eax jmp .LBB5_1 .LBB5_3: addl %edx, %eax .align 16, 0x90 .LBB5_1: cmpq %rdi, %rcx je .LBB5_4 movl (%rdi), %edx addq $4, %rdi testl %edx, %edx jle .LBB5_1 jmp .LBB5_3 .LBB5_4: retq
  • 8. fn foo(v: &[i32]) -> i32 { v.iter() .filter(|i| **i > 0) .map(|i| *i) .sum() } Higher-level coding 5 
generates the same assembly code.
  • 9. Safe 6 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 }
  • 10. Safe 6 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 } Might free underlying buffer.
  • 11. Safe 6 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.
  • 12. fn parallel_qsort(vec: &mut [int]) { if vec.len() <= 1 { return; } let pivot = vec[random(vec.len())]; let mid = vec.partition(vec, pivot); let (less, greater) = vec.split_at_mut(mid); rayon::join( || parallel_qsort(less), || parallel_qsort(greater) ); } Parallel 7Caveat: shameless plug for third-party package of mine.
  • 13. fn parallel_qsort(vec: &mut [int]) { if vec.len() <= 1 { return; } let pivot = vec[random(vec.len())]; let mid = vec.partition(vec, pivot); let (less, greater) = vec.split_at_mut(mid); rayon::join( || parallel_qsort(less), || parallel_qsort(greater) ); } Parallel 7 Sort left and right in parallel.Caveat: shameless plug for third-party package of mine.
  • 14. fn parallel_qsort(vec: &mut [int]) { if vec.len() <= 1 { return; } let pivot = vec[random(vec.len())]; let mid = vec.partition(vec, pivot); let (less, greater) = vec.split_at_mut(mid); rayon::join( || parallel_qsort(less), || parallel_qsort(less) ); } Parallel
 and safe 8 Data race.
  • 15. fn parallel_qsort(vec: &mut [int]) { if vec.len() <= 1 { return; } let pivot = vec[random(vec.len())]; let mid = vec.partition(vec, pivot); let (less, greater) = vec.split_at_mut(mid); rayon::join( || parallel_qsort(less), || parallel_qsort(less) ); } Parallel
 and safe 8 error: closure requires unique access to `less` but it is already borrowed || parallel_qsort(less) ^~~~~~~~~~~~~~~~~~~~~~~ Data race.
  • 16. Open and welcoming Rust has been open source from the beginning. ! Open governance model based on public RFCs. ! We have an active, amazing community. ❀ 9
  • 17. The Plan 10 1. Hello, world! 2. Structs and such. 3. Threads.
  • 19. Hello, world! 12 smallcultfollowing.com/20151209/ ! Example “Hello World” fn main() { println!(“Hello, world!”); }
  • 20. Ownership! ! n. The act, state, or right of possessing something. 13 Borrow! ! v. To receive something with the promise of returning it.
  • 26. fn main() { let name = format!(“
”); helper(name); helper(name); } fn helper(name: String) { println!(..); } ! ! ! Ownership 16
  • 27. fn main() { let name = format!(“
”); helper(name); helper(name); } fn helper(name: String) { println!(..); } ! ! ! Ownership 16
  • 28. fn main() { let name = format!(“
”); helper(name); helper(name); } fn helper(name: String) { println!(..); } ! ! ! Ownership Take ownership of a String 16
  • 29. fn main() { let name = format!(“
”); helper(name); helper(name); } fn helper(name: String) { println!(..); } ! ! ! Ownership 16
  • 30. fn main() { let name = format!(“
”); helper(name); helper(name); } fn helper(name: String) { println!(..); } ! ! ! Ownership 16
  • 31. fn main() { let name = format!(“
”); helper(name); helper(name); } fn helper(name: String) { println!(..); } ! ! ! Ownership 16
  • 32. fn main() { let name = format!(“
”); helper(name); helper(name); } fn helper(name: String) { println!(..); } ! ! ! Ownership 16
  • 33. fn main() { let name = format!(“
”); helper(name); helper(name); } fn helper(name: String) { println!(..); } ! ! ! Ownership 16
  • 34. fn main() { let name = format!(“
”); helper(name); helper(name); } fn helper(name: String) { println!(..); } ! ! ! Ownership 16
  • 35. fn main() { let name = format!(“
”); helper(name); helper(name); } fn helper(name: String) { println!(..); } ! ! ! Ownership 16 Error: use of moved value: `name`
  • 36. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17
  • 37. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17
  • 38. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java Take reference to Vector 17
  • 39. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17
  • 40. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17
  • 41. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17
  • 42. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17
  • 43. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17
  • 44. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17
  • 45. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17
  • 46. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17
  • 47. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17
  • 48. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17 new Thread(
);
  • 49. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17 new Thread(
);
  • 50. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17 new Thread(
);
  • 51. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17 new Thread(
);
  • 52. void main() { Vector name = 
; helper(name); helper(name); } void helper(Vector name) { 
 } ! ! ! “Ownership” in Java 17 new Thread(
);
  • 53. Clone 18 fn main() { let name = format!(“
”); helper(name.clone()); helper(name); } fn helper(name: String) { println!(..); } ! ! !
  • 54. Clone 18 fn main() { let name = format!(“
”); helper(name.clone()); helper(name); } fn helper(name: String) { println!(..); } ! ! !
  • 55. Clone 18 fn main() { let name = format!(“
”); helper(name.clone()); helper(name); } fn helper(name: String) { println!(..); } ! ! ! Copy the String
  • 56. Clone 18 fn main() { let name = format!(“
”); helper(name.clone()); helper(name); } fn helper(name: String) { println!(..); } ! ! !
  • 57. Clone 18 fn main() { let name = format!(“
”); helper(name.clone()); helper(name); } fn helper(name: String) { println!(..); } ! ! !
  • 58. Clone 18 fn main() { let name = format!(“
”); helper(name.clone()); helper(name); } fn helper(name: String) { println!(..); } ! ! !
  • 59. Clone 18 fn main() { let name = format!(“
”); helper(name.clone()); helper(name); } fn helper(name: String) { println!(..); } ! ! !
  • 60. Clone 18 fn main() { let name = format!(“
”); helper(name.clone()); helper(name); } fn helper(name: String) { println!(..); } ! ! !
  • 61. Clone 18 fn main() { let name = format!(“
”); helper(name.clone()); helper(name); } fn helper(name: String) { println!(..); } ! ! !
  • 62. Copy (auto-Clone) 19 fn main() { let name = 22; helper(name); helper(name); } fn helper(name: i32) { println!(..); } ! ! !
  • 63. Copy (auto-Clone) 19 fn main() { let name = 22; helper(name); helper(name); } fn helper(name: i32) { println!(..); } ! ! ! i32 is a Copy type
  • 64. Copy (auto-Clone) 19 fn main() { let name = 22; helper(name); helper(name); } fn helper(name: i32) { println!(..); } ! ! ! i32 is a Copy type
  • 65. Copy (auto-Clone) 19 fn main() { let name = 22; helper(name); helper(name); } fn helper(name: i32) { println!(..); } ! ! ! i32 is a Copy type
  • 66. Copy (auto-Clone) 19 fn main() { let name = 22; helper(name); helper(name); } fn helper(name: i32) { println!(..); } ! ! ! i32 is a Copy type
  • 67. Copy (auto-Clone) 19 fn main() { let name = 22; helper(name); helper(name); } fn helper(name: i32) { println!(..); } ! ! ! i32 is a Copy type
  • 68. 20 Non-copyable: Values move from place to place. Examples: File descriptor, database handle. ! Clone: Run custom code to make a copy. Examples: String, Vector! ! Copy: Type is implicitly copied when referenced. Examples: u32, i32, (f32, i32).
  • 69. Exercise: ownership 21 http://smallcultfollowing.com/20151209 Cheat sheet: fn helper(name: String) // takes ownership ! string.clone() // clone the string http://doc.rust-lang.org/std
  • 73. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow 23
  • 74. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow 23
  • 75. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow 23
  • 76. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow Take a reference to a String 23
  • 77. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow Take a reference to a String 23 Lend the string
  • 78. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow Take a reference to a String 23 Lend the string
  • 79. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow Take a reference to a String 23 Lend the string
  • 80. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow 23
  • 81. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow 23
  • 82. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow 23
  • 83. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow 23
  • 84. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow 23
  • 85. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow 23
  • 86. fn helper(name: &String) { println!(..); } ! ! ! fn main() { let name = format!(“
”); helper(&name); helper(&name); } Shared borrow 23
  • 87. Shared == Immutable 24 fn helper(name: &String) { println!(“{}”, name); } fn helper(name: &String) { name.push_str(“foo”); }
  • 88. Shared == Immutable 24 fn helper(name: &String) { println!(“{}”, name); } fn helper(name: &String) { name.push_str(“foo”); } OK. Just reads.
  • 89. Shared == Immutable 24 fn helper(name: &String) { println!(“{}”, name); } fn helper(name: &String) { name.push_str(“foo”); } OK. Just reads. Error. Writes.
  • 90. Shared == Immutable 24 fn helper(name: &String) { println!(“{}”, name); } fn helper(name: &String) { name.push_str(“foo”); } OK. Just reads. Error. Writes. error: cannot borrow immutable borrowed content `*name` as mutable name.push_str(“s”); ^~~~
  • 91. Shared == Immutable 24 fn helper(name: &String) { println!(“{}”, name); } fn helper(name: &String) { name.push_str(“foo”); } OK. Just reads. Error. Writes. * Actually: mutation only in controlled circumstances. * error: cannot borrow immutable borrowed content `*name` as mutable name.push_str(“s”); ^~~~
  • 92. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25
  • 93. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25
  • 94. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow Take a mutable reference to a String 25
  • 95. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow Take a mutable reference to a String 25 Lend the string mutably
  • 96. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow Take a mutable reference to a String 25 Lend the string mutably
  • 97. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow Take a mutable reference to a String 25 Lend the string mutably
  • 98. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25
  • 99. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25
  • 100. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25
  • 101. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25 Mutate string in place
  • 102. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25
  • 103. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25
  • 104. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25
  • 105. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25
  • 106. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25
  • 107. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25 Prints the updated string.
  • 108. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25
  • 109. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25
  • 110. fn update(name: &mut String) { name.push_str(“
”); } ! ! ! fn main() { let mut name = 
; update(&mut name); println!(“{}”, name); } Mutable borrow 25
  • 112. .capacity: 
 .len: 10 fn helper(name: &String) { println!(..); } ! ! ! 27 fn main() name.data fn main() { let name = format!(“
”); helper(&name); helper(&name); } ‘R’ ‘u’ 
 ‘n’ ‘s’
  • 113. .capacity: 
 .len: 10 fn helper(name: &String) { println!(..); } ! ! ! 27 fn main() name.data fn main() { let name = format!(“
”); helper(&name); helper(&name); } ‘R’ ‘u’ 
 ‘n’ ‘s’
  • 114. .capacity: 
 .len: 10 fn helper(name: &String) { println!(..); } ! ! ! 27 fn main() name.data fn main() { let name = format!(“
”); helper(&name); helper(&name); } ‘R’ ‘u’ 
 ‘n’ ‘s’
  • 115. .capacity: 
 .len: 10 fn helper(name: &String) { println!(..); } ! ! ! 27 fn main() name.data fn helper() name fn main() { let name = format!(“
”); helper(&name); helper(&name); } String owned by somebody else up the stack. ‘R’ ‘u’ 
 ‘n’ ‘s’
  • 116. .capacity: 
 .len: 10 fn helper(name: &str) { ! } 28 fn main() name.data fn helper() name.data fn main() { let name = format!(“
”); helper(&name[1..9]); helper(&name); } .len: 8 ‘R’ ‘u’ 
 ‘n’ ‘s’ “ustacean”
  • 117. .capacity: 
 .len: 10 fn helper(name: &str) { ! } 28 fn main() name.data fn helper() name.data fn main() { let name = format!(“
”); helper(&name[1..9]); helper(&name); } .len: 8 ‘R’ ‘u’ 
 ‘n’ ‘s’ “ustacean”
  • 118. .capacity: 
 .len: 10 fn helper(name: &str) { ! } 28 fn main() name.data fn helper() name.data fn main() { let name = format!(“
”); helper(&name[1..9]); helper(&name); } .len: 8 ‘R’ ‘u’ 
 ‘n’ ‘s’ “ustacean”
  • 119. .capacity: 
 .len: 10 fn helper(name: &str) { ! } 28 fn main() name.data fn helper() name.data fn main() { let name = format!(“
”); helper(&name[1..9]); helper(&name); } .len: 8 ‘R’ ‘u’ 
 ‘n’ ‘s’ “ustacean”
  • 120. .capacity: 
 .len: 10 fn helper(name: &str) { ! } 28 fn main() name.data fn helper() name.data fn main() { let name = format!(“
”); helper(&name[1..9]); helper(&name); } .len: 8 ‘R’ ‘u’ 
 ‘n’ ‘s’ “ustacean” Subslice of a string owned up the stack
  • 121. .capacity: 
 .len: 10 fn helper(name: &str) { ! } 28 fn main() name.data fn helper() name.data fn main() { let name = format!(“
”); helper(&name[1..9]); helper(&name); } .len: 8 ‘R’ ‘u’ 
 ‘n’ ‘s’ “ustacean”
  • 122. .capacity: 
 .len: 10 fn helper(name: &str) { ! } 28 fn main() name.data fn helper() name.data fn main() { let name = format!(“
”); helper(&name[1..9]); helper(&name); } .len: 8 ‘R’ ‘u’ 
 ‘n’ ‘s’ “ustacean” helper(&name[1..]);
  • 123. .capacity: 
 .len: 10 fn helper(name: &str) { ! } 28 fn main() name.data fn helper() name.data fn main() { let name = format!(“
”); helper(&name[1..9]); helper(&name); } .len: 8 ‘R’ ‘u’ 
 ‘n’ ‘s’ “ustacean” helper(&name[1..]); “stacean” 7
  • 124. .capacity: 
 .len: 10 fn helper(name: &str) { ! } 28 fn main() name.data fn helper() name.data fn main() { let name = format!(“
”); helper(&name[1..9]); helper(&name); } .len: 8 ‘R’ ‘u’ 
 ‘n’ ‘s’ “ustacean” helper(&name[1..]); “stacean” 7
  • 125. .capacity: 
 .len: 10 fn helper(name: &str) { ! } 28 fn main() name.data fn helper() name.data fn main() { let name = format!(“
”); helper(&name[1..9]); helper(&name); } .len: 8 ‘R’ ‘u’ 
 ‘n’ ‘s’ “ustacean” helper(&name[1..]); “stacean” 7
  • 126. .capacity: 
 .len: 10 fn helper(name: &str) { ! } 28 fn main() name.data fn helper() name.data fn main() { let name = format!(“
”); helper(&name[1..9]); helper(&name); } .len: 8 ‘R’ ‘u’ 
 ‘n’ ‘s’ “ustacean” helper(&name[1..]); “stacean” 7
  • 127. data len data len String data len capacity String data len capacity ‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’ 29 “Rustaceans”: &str format!(“Rustaceans”): String 
Rustaceans

  • 128. data len data len String data len capacity String data len capacity ‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’ 29 “Rustaceans”: &str format!(“Rustaceans”): String 
Rustaceans

  • 129. data len data len String data len capacity String data len capacity ‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’ 29 “Rustaceans”: &str format!(“Rustaceans”): String 
Rustaceans

  • 130. data len data len String data len capacity String data len capacity ‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’ 29 “Rustaceans”: &str format!(“Rustaceans”): String 
Rustaceans

  • 131. data len data len String data len capacity String data len capacity ‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’ 29 “Rustaceans”: &str format!(“Rustaceans”): String 
Rustaceans

  • 132. data len data len String data len capacity String data len capacity ‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’ 29 “Rustaceans”: &str format!(“Rustaceans”): String 
Rustaceans
 &’static str
  • 133. data len data len String data len capacity String data len capacity ‘R’ ‘u’ 
 ‘s’‘R’ ‘u’ 
 ‘s’ 29 “Rustaceans”: &str format!(“Rustaceans”): String 
Rustaceans
 &’static str
  • 135. GC vs C++ vs Rust 31 GC’d language (e.g. Java) One size ïŹts all `void helper(String name)` temporary access? start a thread? store in a static? Rust Temporary references — conïŹned to owner’s scope Data cannot be freed or mutated while reference is live C++ No clear rules Easily invalidated “Don’t make mistakes”
  • 136. GC vs C++ vs Rust 31 GC’d language (e.g. Java) One size ïŹts all `void helper(String name)` temporary access? start a thread? store in a static? Rust Temporary references — conïŹned to owner’s scope Data cannot be freed or mutated while reference is live C++ No clear rules Easily invalidated “Don’t make mistakes”
  • 137. GC vs C++ vs Rust 31 GC’d language (e.g. Java) One size ïŹts all `void helper(String name)` temporary access? start a thread? store in a static? Rust Temporary references — conïŹned to owner’s scope Data cannot be freed or mutated while reference is live C++ No clear rules Easily invalidated “Don’t make mistakes”
  • 138. GC vs C++ vs Rust 31 GC’d language (e.g. Java) One size ïŹts all `void helper(String name)` temporary access? start a thread? store in a static? Rust Temporary references — conïŹned to owner’s scope Data cannot be freed or mutated while reference is live C++ No clear rules Easily invalidated “Don’t make mistakes”
  • 139. GC vs C++ vs Rust 31 GC’d language (e.g. Java) One size ïŹts all `void helper(String name)` temporary access? start a thread? store in a static? Rust Temporary references — conïŹned to owner’s scope Data cannot be freed or mutated while reference is live C++ No clear rules Easily invalidated “Don’t make mistakes”
  • 140. GC vs C++ vs Rust 31 GC’d language (e.g. Java) One size ïŹts all `void helper(String name)` temporary access? start a thread? store in a static? Rust Temporary references — conïŹned to owner’s scope Data cannot be freed or mutated while reference is live C++ No clear rules Easily invalidated “Don’t make mistakes”
  • 141. GC vs C++ vs Rust 31 GC’d language (e.g. Java) One size ïŹts all `void helper(String name)` temporary access? start a thread? store in a static? Rust Temporary references — conïŹned to owner’s scope Data cannot be freed or mutated while reference is live C++ No clear rules Easily invalidated “Don’t make mistakes”
  • 142. GC vs C++ vs Rust 31 GC’d language (e.g. Java) One size ïŹts all `void helper(String name)` temporary access? start a thread? store in a static? Rust Temporary references — conïŹned to owner’s scope Data cannot be freed or mutated while reference is live C++ No clear rules Easily invalidated “Don’t make mistakes”
  • 143. GC vs C++ vs Rust 31 GC’d language (e.g. Java) One size ïŹts all `void helper(String name)` temporary access? start a thread? store in a static? Rust Temporary references — conïŹned to owner’s scope Data cannot be freed or mutated while reference is live C++ No clear rules Easily invalidated “Don’t make mistakes”
  • 144. GC vs C++ vs Rust 31 GC’d language (e.g. Java) One size ïŹts all `void helper(String name)` temporary access? start a thread? store in a static? Rust Temporary references — conïŹned to owner’s scope Data cannot be freed or mutated while reference is live C++ No clear rules Easily invalidated “Don’t make mistakes”
  • 145. GC vs C++ vs Rust 31 GC’d language (e.g. Java) One size ïŹts all `void helper(String name)` temporary access? start a thread? store in a static? Rust Temporary references — conïŹned to owner’s scope Data cannot be freed or mutated while reference is live C++ No clear rules Easily invalidated “Don’t make mistakes”
  • 146. 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); }
  • 147. 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); }
  • 148. 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r
  • 149. 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r
  • 150. 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r
  • 151. .capacity: 
 .len: 10 name.data ‘R’ ‘u’ 
 ‘n’ ‘s’ 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r
  • 152. .capacity: 
 .len: 10 name.data ‘R’ ‘u’ 
 ‘n’ ‘s’ 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r
  • 153. .capacity: 
 .len: 10 name.data ‘R’ ‘u’ 
 ‘n’ ‘s’ 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r
  • 154. .capacity: 
 .len: 10 name.data ‘R’ ‘u’ 
 ‘n’ ‘s’ 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r
  • 155. .capacity: 
 .len: 10 name.data ‘R’ ‘u’ 
 ‘n’ ‘s’ 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r
  • 156. .capacity: 
 .len: 10 name.data ‘R’ ‘u’ 
 ‘n’ ‘s’ 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r
  • 157. .capacity: 
 .len: 10 name.data ‘R’ ‘u’ 
 ‘n’ ‘s’ 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r
  • 158. .capacity: 
 .len: 10 name.data ‘R’ ‘u’ 
 ‘n’ ‘s’ 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r
  • 159. .capacity: 
 .len: 10 name.data ‘R’ ‘u’ 
 ‘n’ ‘s’ 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r
  • 160. .capacity: 
 .len: 10 name.data ‘R’ ‘u’ 
 ‘n’ ‘s’ 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r Dangling reference!
  • 161. .capacity: 
 .len: 10 name.data ‘R’ ‘u’ 
 ‘n’ ‘s’ 32 fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } r Dangling reference!
  • 162. fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } 33http://is.gd/HJyO7A
  • 163. fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } 33http://is.gd/HJyO7A
  • 164. fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } 33 Lifetime: span of code where reference is used. http://is.gd/HJyO7A
  • 165. fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } 33 Lifetime: span of code where reference is used. http://is.gd/HJyO7A
  • 166. fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } 33 Lifetime: span of code where reference is used. http://is.gd/HJyO7A
  • 167. fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } 33 Lifetime: span of code where reference is used. http://is.gd/HJyO7A
  • 168. fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } 33 Lifetime: span of code where reference is used. http://is.gd/HJyO7A
  • 169. fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } 33 Lifetime: span of code where reference is used. http://is.gd/HJyO7A
  • 170. fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } 33 ‘l Lifetime: span of code where reference is used. http://is.gd/HJyO7A
  • 171. fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } 33 ‘l Lifetime: span of code where reference is used. Scope of data being borrowed (here, `name`) compared against http://is.gd/HJyO7A
  • 172. ‘s fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } 33 ‘l Lifetime: span of code where reference is used. Scope of data being borrowed (here, `name`) compared against http://is.gd/HJyO7A
  • 173. ‘s fn main() { let r; { let name = format!(“
”); r = &name; } println!(“{}”, r); } 33 ‘l Lifetime: span of code where reference is used. Scope of data being borrowed (here, `name`) compared against http://is.gd/HJyO7A error: `name` does not live long enough r = &name; ^~~~
  • 174. 34 use std::thread; ! fn helper(name: &String) { thread::spawn(move || { use(name); }); }
  • 175. 34 use std::thread; ! fn helper(name: &String) { thread::spawn(move || { use(name); }); } `name` can only be used within this fn
  • 176. 34 use std::thread; ! fn helper(name: &String) { thread::spawn(move || { use(name); }); } `name` can only be used within this fn
  • 177. 34 use std::thread; ! fn helper(name: &String) { thread::spawn(move || { use(name); }); } `name` can only be used within this fn
  • 178. 34 use std::thread; ! fn helper(name: &String) { thread::spawn(move || { use(name); }); } `name` can only be used within this fn Might escape the function!
  • 179. 34 use std::thread; ! fn helper(name: &String) { thread::spawn(move || { use(name); }); } `name` can only be used within this fn Might escape the function! error: the type `[
]` does not fulfill the required lifetime thread::spawn(move || { ^~~~~~~~~~~~~ note: type must outlive the static lifetime
  • 180. 34 use std::thread; ! fn helper(name: &String) { thread::spawn(move || { use(name); }); } `name` can only be used within this fn error: the type `[
]` does not fulfill the required lifetime thread::spawn(move || { ^~~~~~~~~~~~~ note: type must outlive the static lifetime
  • 181. 34 use std::thread; ! fn helper(name: &String) { thread::spawn(move || { use(name); }); } `name` can only be used within this fn error: the type `[
]` does not fulfill the required lifetime thread::spawn(move || { ^~~~~~~~~~~~~ note: type must outlive the static lifetime
  • 182. 34 use std::thread; ! fn helper(name: &String) { thread::spawn(move || { use(name); }); } `name` can only be used within this fn error: the type `[
]` does not fulfill the required lifetime thread::spawn(move || { ^~~~~~~~~~~~~ note: type must outlive the static lifetime
  • 183. 34 use std::thread; ! fn helper(name: &String) { thread::spawn(move || { use(name); }); } `name` can only be used within this fn error: the type `[
]` does not fulfill the required lifetime thread::spawn(move || { ^~~~~~~~~~~~~ note: type must outlive the static lifetime However: see crossbeam, simple_parallel, etc on crates.io
  • 184. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice);
  • 185. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice);
  • 186. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); ‘R’ ‘u’ 
 ‘n’ String data len capacity
  • 187. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); ‘R’ ‘u’ 
 ‘n’ String data len capacity
  • 188. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); ‘R’ ‘u’ 
 ‘n’ String data len capacity
  • 189. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); ‘R’ ‘u’ 
 ‘n’ String data len capacity data len
  • 190. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); ‘R’ ‘u’ 
 ‘n’ String data len capacity data len
  • 191. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); ‘R’ ‘u’ 
 ‘n’ String data len capacity data len
  • 192. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); ‘R’ ‘u’ 
 ‘n’ String data len capacity ‘R’ ‘u’ 
 ‘n’ data len
  • 193. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); ‘R’ ‘u’ 
 ‘n’ String data len capacity ‘R’ ‘u’ 
 ‘n’ data len ‘s’
  • 194. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); String data len capacity ‘R’ ‘u’ 
 ‘n’ data len ‘R’ ‘u’ 
 ‘n’ ‘s’
  • 195. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); String data len capacity ‘R’ ‘u’ 
 ‘n’ data len ‘R’ ‘u’ 
 ‘n’ ‘s’
  • 196. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); String data len capacity ‘R’ ‘u’ 
 ‘n’ data len ‘R’ ‘u’ 
 ‘n’ ‘s’
  • 197. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); String data len capacity ‘R’ ‘u’ 
 ‘n’ data len ‘R’ ‘u’ 
 ‘n’ ‘s’ Dangling reference!
  • 198. Dangers of mutation 35 let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); String data len capacity ‘R’ ‘u’ 
 ‘n’ data len ‘R’ ‘u’ 
 ‘n’ ‘s’ Dangling reference!
  • 199. Rust solution 36 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.
  • 200. Dangers of mutation 37 fn main() { let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); } http://is.gd/MCPVWg
  • 201. Dangers of mutation 37 fn main() { let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); } http://is.gd/MCPVWg
  • 202. Dangers of mutation 37 fn main() { let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); } Borrow “locks” `buffer` until `slice` goes out of scope http://is.gd/MCPVWg
  • 203. Dangers of mutation 37 fn main() { let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); } Borrow “locks” `buffer` until `slice` goes out of scope http://is.gd/MCPVWg
  • 204. Dangers of mutation 37 fn main() { let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); } Borrow “locks” `buffer` until `slice` goes out of scope error: cannot borrow `buffer` as mutable because it is also borrowed as immutable buffer.push_str(“s”); ^~~~~~ http://is.gd/MCPVWg
  • 205. Dangers of mutation 37 fn main() { let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice); } Borrow “locks” `buffer` until `slice` goes out of scope error: cannot borrow `buffer` as mutable because it is also borrowed as immutable buffer.push_str(“s”); ^~~~~~ http://is.gd/MCPVWg
  • 206. fn main() { let mut buffer: String = format!(“Rustacean”); for i in 0 .. buffer.len() { let slice = &buffer[i..]; buffer.push_str(“s”); println!(“{:?}”, slice); } buffer.push_str(“s”); } 38
  • 207. fn main() { let mut buffer: String = format!(“Rustacean”); for i in 0 .. buffer.len() { let slice = &buffer[i..]; buffer.push_str(“s”); println!(“{:?}”, slice); } buffer.push_str(“s”); } 38 Borrow “locks” `buffer` until `slice` goes out of scope
  • 208. fn main() { let mut buffer: String = format!(“Rustacean”); for i in 0 .. buffer.len() { let slice = &buffer[i..]; buffer.push_str(“s”); println!(“{:?}”, slice); } buffer.push_str(“s”); } 38 Borrow “locks” `buffer` until `slice` goes out of scope
  • 209. fn main() { let mut buffer: String = format!(“Rustacean”); for i in 0 .. buffer.len() { let slice = &buffer[i..]; buffer.push_str(“s”); println!(“{:?}”, slice); } buffer.push_str(“s”); } 38 Borrow “locks” `buffer` until `slice` goes out of scope
  • 210. fn main() { let mut buffer: String = format!(“Rustacean”); for i in 0 .. buffer.len() { let slice = &buffer[i..]; buffer.push_str(“s”); println!(“{:?}”, slice); } buffer.push_str(“s”); } 38 Borrow “locks” `buffer` until `slice` goes out of scope OK: `buffer` is not borrowed here
  • 211. Exercise: borrowing 39 http://smallcultfollowing.com/20151209 Cheat sheet: &String // type of shared reference &mut String // type of mutable reference &str // type of string slice ! &name // shared borrow &mut name // mutable borrow &name[x..y] // slice expression http://doc.rust-lang.org/std
  • 213. 41 Shop till you drop! By QuentinUK (Own work), via Wikimedia Commons
  • 214. Declaring a structure 42 struct Store { name: String, prices: Vec<Item>, }
  • 215. Declaring a structure 42 struct Store { name: String, prices: Vec<Item>, }
  • 216. Declaring a structure 42 struct Store { name: String, prices: Vec<Item>, }
  • 217. Declaring a structure 42 struct Store { name: String, prices: Vec<Item>, }
  • 218. Declaring a structure 42 struct Store { name: String, prices: Vec<Item>, }
  • 219. Declaring a structure 42 struct Store { name: String, prices: Vec<Item>, }
  • 220. Declaring a structure 42 struct Store { name: String, prices: Vec<Item>, }
  • 221. Declaring a structure 42 struct Store { name: String, prices: Vec<Item>, }
  • 222. Declaring a structure 42 struct Store { name: String, prices: Vec<Item>, }
  • 223. Declaring a structure 42 struct Store { name: String, prices: Vec<Item>, } name prices
  • 224. Declaring a structure 42 struct Store { name: String, prices: Vec<Item>, } name prices .length .data .capacity .length .data .capacity
  • 225. Declaring a structure 42 struct Store { name: String, prices: Vec<Item>, } Item name prices ‘R’ ‘u’ 
 ‘n’ Item Item .length .data .capacity .length .data .capacity
  • 226. Declaring a structure 42 struct Store { name: String, prices: Vec<Item>, } Item name prices ‘R’ ‘u’ 
 ‘n’ Item Item .length .data .capacity .length .data .capacity
  • 227. 43 struct Item { name: &’static str, price: f32, } Other fundamental types f32 f64 ! ! i8 i16 i32 i64 isize u8 u16 u32 u64 usize &str &[T] ! ! ïŹ‚oats signed unsigned slices
  • 228. 43 struct Item { name: &’static str, price: f32, } Other fundamental types f32 f64 ! ! i8 i16 i32 i64 isize u8 u16 u32 u64 usize &str &[T] ! ! ïŹ‚oats signed unsigned slices
  • 229. 43 struct Item { name: &’static str, price: f32, } Other fundamental types f32 f64 ! ! i8 i16 i32 i64 isize u8 u16 u32 u64 usize &str &[T] ! ! ïŹ‚oats signed unsigned slices
  • 230. 43 struct Item { name: &’static str, price: f32, } Other fundamental types f32 f64 ! ! i8 i16 i32 i64 isize u8 u16 u32 u64 usize &str &[T] ! ! ïŹ‚oats signed unsigned slices
  • 231. 43 struct Item { name: &’static str, price: f32, } Other fundamental types f32 f64 ! ! i8 i16 i32 i64 isize u8 u16 u32 u64 usize &str &[T] ! ! ïŹ‚oats signed unsigned slices
  • 232. 43 struct Item { name: &’static str, price: f32, } Other fundamental types f32 f64 ! ! i8 i16 i32 i64 isize u8 u16 u32 u64 usize &str &[T] ! ! ïŹ‚oats signed unsigned slices
  • 233. 43 struct Item { name: &’static str, price: f32, } Other fundamental types f32 f64 ! ! i8 i16 i32 i64 isize u8 u16 u32 u64 usize &str &[T] ! ! ïŹ‚oats signed unsigned slices
  • 234. 43 struct Item { name: &’static str, price: f32, } Other fundamental types f32 f64 ! ! i8 i16 i32 i64 isize u8 u16 u32 u64 usize &str &[T] ! ! ïŹ‚oats signed unsigned slices
  • 235. 43 struct Item { name: &’static str, price: f32, } Other fundamental types f32 f64 ! ! i8 i16 i32 i64 isize u8 u16 u32 u64 usize &str &[T] ! ! ïŹ‚oats signed unsigned slices
  • 236. 43 struct Item { name: &’static str, price: f32, } Other fundamental types f32 f64 ! ! i8 i16 i32 i64 isize u8 u16 u32 u64 usize &str &[T] ! ! ïŹ‚oats signed unsigned slices
  • 237. 43 struct Item { name: &’static str, price: f32, } Other fundamental types f32 f64 ! ! i8 i16 i32 i64 isize u8 u16 u32 u64 usize &str &[T] ! ! ïŹ‚oats signed unsigned slices
  • 238. 43 struct Item { name: &’static str, price: f32, } Other fundamental types f32 f64 ! ! i8 i16 i32 i64 isize u8 u16 u32 u64 usize &str &[T] ! ! ïŹ‚oats signed unsigned slices
  • 239. 43 struct Item { name: &’static str, price: f32, } Other fundamental types f32 f64 ! ! i8 i16 i32 i64 isize u8 u16 u32 u64 usize &str &[T] ! ! ïŹ‚oats signed unsigned slices
  • 240. Methods 44 struct Store { .. } struct Item { .. } ! impl Store { fn add_item(&mut self, item: Item) { self.items.push(item); } ! fn price(&self, item_name: &str) -> f32 { 
 // see upcoming slide } }
  • 241. Methods 44 struct Store { .. } struct Item { .. } ! impl Store { fn add_item(&mut self, item: Item) { self.items.push(item); } ! fn price(&self, item_name: &str) -> f32 { 
 // see upcoming slide } }
  • 242. Methods 44 struct Store { .. } struct Item { .. } ! impl Store { fn add_item(&mut self, item: Item) { self.items.push(item); } ! fn price(&self, item_name: &str) -> f32 { 
 // see upcoming slide } }
  • 243. Methods 44 struct Store { .. } struct Item { .. } ! impl Store { fn add_item(&mut self, item: Item) { self.items.push(item); } ! fn price(&self, item_name: &str) -> f32 { 
 // see upcoming slide } } store.add_item(
); // must be let mut store.price(
); // let OR let mut
  • 244. Methods 44 struct Store { .. } struct Item { .. } ! impl Store { fn add_item(&mut self, item: Item) { self.items.push(item); } ! fn price(&self, item_name: &str) -> f32 { 
 // see upcoming slide } } store.add_item(
); // must be let mut store.price(
); // let OR let mut
  • 245. Methods 44 struct Store { .. } struct Item { .. } ! impl Store { fn add_item(&mut self, item: Item) { self.items.push(item); } ! fn price(&self, item_name: &str) -> f32 { 
 // see upcoming slide } } store.add_item(
); // must be let mut store.price(
); // let OR let mut itself an &mut method
  • 246. Methods 44 struct Store { .. } struct Item { .. } ! impl Store { fn add_item(&mut self, item: Item) { self.items.push(item); } ! fn price(&self, item_name: &str) -> f32 { 
 // see upcoming slide } } store.add_item(
); // must be let mut store.price(
); // let OR let mut
  • 247. Methods 44 struct Store { .. } struct Item { .. } ! impl Store { fn add_item(&mut self, item: Item) { self.items.push(item); } ! fn price(&self, item_name: &str) -> f32 { 
 // see upcoming slide } } store.add_item(
); // must be let mut store.price(
); // let OR let mut
  • 248. Methods 44 struct Store { .. } struct Item { .. } ! impl Store { fn add_item(&mut self, item: Item) { self.items.push(item); } ! fn price(&self, item_name: &str) -> f32 { 
 // see upcoming slide } } store.add_item(
); // must be let mut store.price(
); // let OR let mut
  • 249. Methods 44 struct Store { .. } struct Item { .. } ! impl Store { fn add_item(&mut self, item: Item) { self.items.push(item); } ! fn price(&self, item_name: &str) -> f32 { 
 // see upcoming slide } } store.add_item(
); // must be let mut store.price(
); // let OR let mut
  • 250. Methods 44 struct Store { .. } struct Item { .. } ! impl Store { fn add_item(&mut self, item: Item) { self.items.push(item); } ! fn price(&self, item_name: &str) -> f32 { 
 // see upcoming slide } } store.add_item(
); // must be let mut store.price(
); // let OR let mut
  • 251. Methods 44 struct Store { .. } struct Item { .. } ! impl Store { fn add_item(&mut self, item: Item) { self.items.push(item); } ! fn price(&self, item_name: &str) -> f32 { 
 // see upcoming slide } } store.add_item(
); // must be let mut store.price(
); // let OR let mut
  • 252. Methods 45 struct Store { .. } ! impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }
  • 253. Methods 45 struct Store { .. } ! impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }
  • 254. Methods 45 struct Store { .. } ! impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } } Store::new(some_name)
  • 255. Methods 45 struct Store { .. } ! impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } } Store::new(some_name)
  • 256. Methods 45 struct Store { .. } ! impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } } Store::new(some_name)
  • 257. Methods 45 struct Store { .. } ! impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } } Store::new(some_name)
  • 258. Methods 45 struct Store { .. } ! impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } } Store::new(some_name)
  • 259. Methods 45 struct Store { .. } ! impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } } Store::new(some_name)
  • 260. Methods 45 struct Store { .. } ! impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } } Store::new(some_name)
  • 261. Methods 45 struct Store { .. } ! impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } } Store::new(some_name)
  • 262. Methods 45 struct Store { .. } ! impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } } Store::new(some_name)
  • 263. Methods 45 struct Store { .. } ! impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } } Store::new(some_name)
  • 264. Return is optional 46 struct Store { .. } ! impl Store { fn new(name: String) -> Store { Store { name: name, items: vec![], } } }
  • 265. Return is optional 46 struct Store { .. } ! impl Store { fn new(name: String) -> Store { Store { name: name, items: vec![], } } } No `;` on last expression: “return this value”
  • 266. Options and Enums 47 enum Option<T> { Some(T), None } fn main() { let v: Option<i32> = Some(22); match v { Some(x) => println!(“v = {}”, x), None => println!(“v = None”), } println!(“v = {}”, v.unwrap()); // risky } http://is.gd/Gfum32
  • 267. Options and Enums 47 enum Option<T> { Some(T), None } fn main() { let v: Option<i32> = Some(22); match v { Some(x) => println!(“v = {}”, x), None => println!(“v = None”), } println!(“v = {}”, v.unwrap()); // risky } http://is.gd/Gfum32
  • 268. Options and Enums 47 enum Option<T> { Some(T), None } fn main() { let v: Option<i32> = Some(22); match v { Some(x) => println!(“v = {}”, x), None => println!(“v = None”), } println!(“v = {}”, v.unwrap()); // risky } http://is.gd/Gfum32
  • 269. Options and Enums 47 enum Option<T> { Some(T), None } fn main() { let v: Option<i32> = Some(22); match v { Some(x) => println!(“v = {}”, x), None => println!(“v = None”), } println!(“v = {}”, v.unwrap()); // risky } http://is.gd/Gfum32
  • 270. Options and Enums 47 enum Option<T> { Some(T), None } fn main() { let v: Option<i32> = Some(22); match v { Some(x) => println!(“v = {}”, x), None => println!(“v = None”), } println!(“v = {}”, v.unwrap()); // risky } http://is.gd/Gfum32
  • 271. Options and Enums 47 enum Option<T> { Some(T), None } fn main() { let v: Option<i32> = Some(22); match v { Some(x) => println!(“v = {}”, x), None => println!(“v = None”), } println!(“v = {}”, v.unwrap()); // risky } http://is.gd/Gfum32
  • 272. Options and Enums 47 enum Option<T> { Some(T), None } fn main() { let v: Option<i32> = Some(22); match v { Some(x) => println!(“v = {}”, x), None => println!(“v = None”), } println!(“v = {}”, v.unwrap()); // risky } http://is.gd/Gfum32
  • 273. Options and Enums 47 enum Option<T> { Some(T), None } fn main() { let v: Option<i32> = Some(22); match v { Some(x) => println!(“v = {}”, x), None => println!(“v = None”), } println!(“v = {}”, v.unwrap()); // risky } http://is.gd/Gfum32
  • 274. Options and Enums 47 enum Option<T> { Some(T), None } fn main() { let v: Option<i32> = Some(22); match v { Some(x) => println!(“v = {}”, x), None => println!(“v = None”), } println!(“v = {}”, v.unwrap()); // risky } http://is.gd/Gfum32
  • 275. Options and Enums 47 enum Option<T> { Some(T), None } fn main() { let v: Option<i32> = Some(22); match v { Some(x) => println!(“v = {}”, x), None => println!(“v = None”), } println!(“v = {}”, v.unwrap()); // risky } http://is.gd/Gfum32
  • 276. Options and Enums 47 enum Option<T> { Some(T), None } fn main() { let v: Option<i32> = Some(22); match v { Some(x) => println!(“v = {}”, x), None => println!(“v = None”), } println!(“v = {}”, v.unwrap()); // risky } http://is.gd/Gfum32
  • 277. For Loops 48 fn main() { let v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; for s in v { println!(“{:?}”, s); } } http://is.gd/6kJc0O “Alpha” “Beta” “Gamma” v: s:
  • 278. For Loops 48 fn main() { let v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; for s in v { println!(“{:?}”, s); } } http://is.gd/6kJc0O “Alpha” “Beta” “Gamma” v: s:
  • 279. For Loops 48 fn main() { let v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; for s in v { println!(“{:?}”, s); } } http://is.gd/6kJc0O “Alpha” “Beta” “Gamma” v: s:
  • 280. For Loops 48 fn main() { let v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; for s in v { println!(“{:?}”, s); } } http://is.gd/6kJc0O “Alpha” “Beta” “Gamma” v: s:
  • 281. For Loops 48 fn main() { let v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; for s in v { println!(“{:?}”, s); } } http://is.gd/6kJc0O “Alpha” “Beta” “Gamma” v: s: Vec<String>
  • 282. For Loops 48 fn main() { let v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; for s in v { println!(“{:?}”, s); } } http://is.gd/6kJc0O “Alpha” “Beta” “Gamma” v: s: String Vec<String>
  • 283. For Loops 48 fn main() { let v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; for s in v { println!(“{:?}”, s); } } http://is.gd/6kJc0O “Alpha” “Beta” “Gamma” v: s:
  • 284. For Loops 48 fn main() { let v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; for s in v { println!(“{:?}”, s); } } http://is.gd/6kJc0O “Alpha” “Beta” “Gamma” v: s:
  • 285. For Loops 48 fn main() { let v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; for s in v { println!(“{:?}”, s); } } http://is.gd/6kJc0O “Beta” “Gamma” v: s:
  • 286. For Loops 48 fn main() { let v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; for s in v { println!(“{:?}”, s); } } http://is.gd/6kJc0O “Beta” “Gamma” v: s:
  • 287. For Loops 48 fn main() { let v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; for s in v { println!(“{:?}”, s); } } http://is.gd/6kJc0O “Gamma” v: s:
  • 288. For Loops 49 fn main() { let mut v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; ! for s in &v { println!(“{:?}”, s); } ! for s in &mut v { s.push_str(“.”); } } “Alpha” “Beta” “Gamma” v:
  • 289. For Loops 49 fn main() { let mut v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; ! for s in &v { println!(“{:?}”, s); } ! for s in &mut v { s.push_str(“.”); } } “Alpha” “Beta” “Gamma” v:
  • 290. For Loops 49 fn main() { let mut v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; ! for s in &v { println!(“{:?}”, s); } ! for s in &mut v { s.push_str(“.”); } } “Alpha” “Beta” “Gamma” v: &Vec<String>
  • 291. For Loops 49 fn main() { let mut v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; ! for s in &v { println!(“{:?}”, s); } ! for s in &mut v { s.push_str(“.”); } } “Alpha” “Beta” “Gamma” v: &String &Vec<String>
  • 292. For Loops 49 fn main() { let mut v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; ! for s in &v { println!(“{:?}”, s); } ! for s in &mut v { s.push_str(“.”); } } “Alpha” “Beta” “Gamma” v:
  • 293. For Loops 49 fn main() { let mut v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; ! for s in &v { println!(“{:?}”, s); } ! for s in &mut v { s.push_str(“.”); } } “Alpha” “Beta” “Gamma” v: s:
  • 294. For Loops 49 fn main() { let mut v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; ! for s in &v { println!(“{:?}”, s); } ! for s in &mut v { s.push_str(“.”); } } “Alpha” “Beta” “Gamma” v: s:
  • 295. For Loops 49 fn main() { let mut v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; ! for s in &v { println!(“{:?}”, s); } ! for s in &mut v { s.push_str(“.”); } } “Alpha” “Beta” “Gamma” v: s:
  • 296. For Loops 49 fn main() { let mut v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; ! for s in &v { println!(“{:?}”, s); } ! for s in &mut v { s.push_str(“.”); } } “Alpha” “Beta” “Gamma” v: s: &mut Vec<String> &mut String
  • 297. For Loops 49 fn main() { let mut v = vec![format!(“Alpha”), format!(“Beta”), format!(“Gamma”)]; ! for s in &v { println!(“{:?}”, s); } ! for s in &mut v { s.push_str(“.”); } } “Alpha” “Beta” “Gamma” v: s:
  • 298. Exercise: structs 50 http://smallcultfollowing.com/20151209 Implement fn total_price(..) Cheat sheet: for s in v { 
 } for s in &v { 
 } let mut some_var = 0.0; println!(“{:?}”, s); some_var += x; while 
 { 
 } http://doc.rust-lang.org/std
  • 303. 53
  • 308. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 309. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 310. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 311. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 312. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 313. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 314. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 315. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 316. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 317. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 318. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 319. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 320. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 321. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 322. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 323. 54 let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } }
  • 324. let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } } 55
  • 325. let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } } 55
  • 326. let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } } 55
  • 327. let mut best = None; let mut best_price = INFINITY; for store in stores { let sum = store.total_price(&shopping_list); match sum { Some(s) if s < best_price => { best = Some(store.name); best_price = s; } _ => { } } } 55
  • 328. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56
  • 329. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56
  • 330. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56
  • 331. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56
  • 332. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56
  • 333. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56
  • 334. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56
  • 335. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56 Closure takes ownership of variables it uses.
  • 336. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56 Closure takes ownership of variables it uses. Variables used by this closure.
  • 337. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56 Closure takes ownership of variables it uses. Variables used by this closure.
  • 338. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56
  • 339. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56 Handle to the thread we spawned.
  • 340. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56
  • 341. Closure body can produce a result, here a (String, f32). use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56
  • 342. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56
  • 343. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56
  • 344. use std::thread; 
 let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } 56
  • 345. 57 let handle = thread::spawn(
);
  • 346. 57 let handle = thread::spawn(
);
  • 347. 57 let handle = thread::spawn(
); 
 // stuff in parallel // with new thread
  • 348. 57 let handle = thread::spawn(
); 
 // stuff in parallel // with new thread let (name, sum) = handle.join().unwrap();
  • 349. 57 let handle = thread::spawn(
); 
 // stuff in parallel // with new thread let (name, sum) = handle.join().unwrap();
  • 350. 57 let handle = thread::spawn(
); 
 // stuff in parallel // with new thread let (name, sum) = handle.join().unwrap(); Wait for thread to ïŹnish and get return value.
  • 351. 57 let handle = thread::spawn(
); 
 // stuff in parallel // with new thread let (name, sum) = handle.join().unwrap(); Wait for thread to ïŹnish and get return value. Result<(String, f32), Error>
  • 352. 57 let handle = thread::spawn(
); 
 // stuff in parallel // with new thread let (name, sum) = handle.join().unwrap(); Wait for thread to ïŹnish and get return value. Thread may have panicked. Propagate.
  • 353. 57 let handle = thread::spawn(
); 
 // stuff in parallel // with new thread let (name, sum) = handle.join().unwrap(); Wait for thread to ïŹnish and get return value. Thread may have panicked. Propagate.Result of thread.
  • 354. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 355. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 356. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 357. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 358. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 359. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 360. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 361. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 362. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 363. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 364. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 365. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 366. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 367. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 368. 58 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { handles.push( thread::spawn(move || { let sum = 
; (store.name, sum) }); } ! for handle in handles { let (name, sum) = handle.join().unwrap(); // find best price }
  • 369. 59 use std::thread; 
 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 370. 59 use std::thread; 
 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } Variables used by this closure.
  • 371. 59 use std::thread; 
 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 372. 59 use std::thread; 
 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 373. 59 use std::thread; 
 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 374. 59 use std::thread; 
 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 375. 59 use std::thread; 
 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } error: capture of moved value: `shopping_list` let sum = store.total_price(&shopping_list); ^~~~~~~~~~~~~ 
 help: perhaps you meant to use `clone()`?
  • 376. 59 use std::thread; 
 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } error: capture of moved value: `shopping_list` let sum = store.total_price(&shopping_list); ^~~~~~~~~~~~~ 
 help: perhaps you meant to use `clone()`?
  • 377. 60 use std::thread; 
 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 378. 60 use std::thread; 
 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 379. 60 use std::thread; 
 let shopping_list = vec![
]; let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 380. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];
  • 381. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];
  • 382. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];
  • 383. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];
  • 384. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];
  • 385. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];
  • 386. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];
  • 387. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];
  • 388. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0]; arc1
  • 389. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0]; arc1
  • 390. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0]; arc1
  • 391. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0]; arc1 arc2
  • 392. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0]; arc1 arc2
  • 393. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0]; arc1 arc2
  • 394. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0]; arc1 arc2 data
  • 395. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0]; arc1 arc2 data
  • 396. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0]; arc1 arc2
  • 397. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0]; arc1
  • 398. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];
  • 399. 61 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];
  • 400. Arc => Immutable 62 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let data = &mut arc1[0]; http://is.gd/nP3Pvb
  • 401. Arc => Immutable 62 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let data = &mut arc1[0]; http://is.gd/nP3Pvb
  • 402. Arc => Immutable 62 use std::sync::Arc; let shopping_list: Vec<ShoppingList> = 
; let arc1 = Arc::new(shopping_list); let data = &mut arc1[0]; <anon>:6:21: 6:24 error: cannot borrow immutable borrowed content as mutable <anon>:6 let data = &mut arc[0]; ^~~ http://is.gd/nP3Pvb
  • 403. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 404. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 405. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 406. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 407. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 408. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 409. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 410. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 411. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 412. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 413. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 414. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 415. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 416. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 417. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 418. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 419. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 420. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); }
  • 421. 63 use std::thread; 
 let shopping_list = Arc::new(vec![
]); let mut handles = vec![]; for store in stores { let shopping_list = shopping_list.clone(); let handle = thread::spawn(move || { let sum = store.total_price(shopping_list); (store.name, sum) }); handles.push(handle); } // exercise (in a bit): join the handles!
  • 423. 65 Joining a thread allows thread to send one result. What if we wanted multiple results?
  • 424. 65 Joining a thread allows thread to send one result. What if we wanted multiple results?
  • 425. 65 Joining a thread allows thread to send one result. What if we wanted multiple results?
  • 426. 65 Joining a thread allows thread to send one result. What if we wanted multiple results?
  • 427. 65 Joining a thread allows thread to send one result. What if we wanted multiple results?
  • 428. 65 Joining a thread allows thread to send one result. What if we wanted multiple results?
  • 429. 65 Joining a thread allows thread to send one result. What if we wanted multiple results? Or if we wanted a response?
  • 430. 65 Joining a thread allows thread to send one result. What if we wanted multiple results? Or if we wanted a response?
  • 431. fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66
  • 432. rx tx fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66
  • 433. rx tx fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66
  • 434. rx tx fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66
  • 435. rx tx fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66 move || { let m = Message::new(); 
 tx.send(m).unwrap(); }
  • 436. rx tx fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66 move || { let m = Message::new(); 
 tx.send(m).unwrap(); }
  • 437. rx tx tx fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66 move || { let m = Message::new(); 
 tx.send(m).unwrap(); }
  • 438. rx tx tx fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66 move || { let m = Message::new(); 
 tx.send(m).unwrap(); }
  • 439. MessageMessage rx tx tx m fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66 move || { let m = Message::new(); 
 tx.send(m).unwrap(); }
  • 440. MessageMessage rx tx tx m fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66 move || { let m = Message::new(); 
 tx.send(m).unwrap(); }
  • 441. Message Message rx tx tx m fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66 move || { let m = Message::new(); 
 tx.send(m).unwrap(); }
  • 442. Message Message rx tx tx m fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66 move || { let m = Message::new(); 
 tx.send(m).unwrap(); }
  • 443. Message Message rx tx tx m fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66 move || { let m = Message::new(); 
 tx.send(m).unwrap(); }
  • 444. Message Message rx tx tx m fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66 move || { let m = Message::new(); 
 tx.send(m).unwrap(); }
  • 445. Message Message rx tx tx m fn parent() { let (tx, rx) = channel(); spawn(move || {
}); let m = rx.recv().unwrap(); } 66 move || { let m = Message::new(); 
 tx.send(m).unwrap(); }
  • 446. 67 rx0 tx0 let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);
  • 447. 67 rx0 tx0 let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);