Top Banner
1 Hack without fear! Nicholas Matsakis
478

Rust Mozlando Tutorial

Apr 13, 2017

Download

Software

nikomatsakis
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Rust Mozlando Tutorial

1

Hack without fear!

Nicholas Matsakis

Page 2: Rust Mozlando Tutorial

2

Systems programming without the hassle

Page 3: Rust Mozlando Tutorial

2

Systems programming without the hasslecrashesheisenbugsfear

Page 4: Rust Mozlando Tutorial

2

Systems programming without the hasslecrashesheisenbugsfear

Parallel!

Page 5: Rust Mozlando Tutorial

// 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

Page 6: Rust Mozlando Tutorial

// 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.

Page 7: Rust Mozlando Tutorial

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

Page 8: Rust Mozlando Tutorial

fn foo(v: &[i32]) -> i32 { v.iter() .filter(|i| **i > 0) .map(|i| *i) .sum() }

Higher-level coding

5

…generates the same assembly code.

Page 9: Rust Mozlando Tutorial

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 }

Page 10: Rust Mozlando Tutorial

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.

Page 11: Rust Mozlando Tutorial

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.

Page 12: Rust Mozlando Tutorial

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.

Page 13: Rust Mozlando Tutorial

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.

Page 14: Rust Mozlando Tutorial

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.

Page 15: Rust Mozlando Tutorial

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.

Page 16: Rust Mozlando Tutorial

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

Page 17: Rust Mozlando Tutorial

The Plan

10

1. Hello, world! 2. Structs and such. 3. Threads.

Page 18: Rust Mozlando Tutorial

11

Hello, world!

Page 19: Rust Mozlando Tutorial

Hello, world!

12

smallcultfollowing.com/20151209/ !

Example “Hello World”

fn main() { println!(“Hello, world!”); }

Page 20: Rust Mozlando Tutorial

Ownership!!n. The act, state, or right of possessing something.

13

Borrow!!v. To receive something with the promise of returning it.

Page 21: Rust Mozlando Tutorial

Ownership/Borrowing

Memory safety

Data-race freedom

No need for a runtime

14

Page 22: Rust Mozlando Tutorial

Ownership/Borrowing

Memory safety

Data-race freedom

No need for a runtime

C++

14

Page 23: Rust Mozlando Tutorial

Ownership/Borrowing

Memory safety

Data-race freedom

No need for a runtime

GCC++

14

Page 24: Rust Mozlando Tutorial

Ownership15

Page 25: Rust Mozlando Tutorial

Ownership15

Page 26: Rust Mozlando Tutorial

fn main() { let name = format!(“…”); helper(name); helper(name); }

fn helper(name: String) { println!(..); } !!!

Ownership 16

Page 27: Rust Mozlando Tutorial

fn main() { let name = format!(“…”); helper(name); helper(name); }

fn helper(name: String) { println!(..); } !!!

Ownership 16

Page 28: Rust Mozlando Tutorial

fn main() { let name = format!(“…”); helper(name); helper(name); }

fn helper(name: String) { println!(..); } !!!

Ownership

Take ownership of a String

16

Page 29: Rust Mozlando Tutorial

fn main() { let name = format!(“…”); helper(name); helper(name); }

fn helper(name: String) { println!(..); } !!!

Ownership 16

Page 30: Rust Mozlando Tutorial

fn main() { let name = format!(“…”); helper(name); helper(name); }

fn helper(name: String) { println!(..); } !!!

Ownership 16

Page 31: Rust Mozlando Tutorial

fn main() { let name = format!(“…”); helper(name); helper(name); }

fn helper(name: String) { println!(..); } !!!

Ownership 16

Page 32: Rust Mozlando Tutorial

fn main() { let name = format!(“…”); helper(name); helper(name); }

fn helper(name: String) { println!(..); } !!!

Ownership 16

Page 33: Rust Mozlando Tutorial

fn main() { let name = format!(“…”); helper(name); helper(name); }

fn helper(name: String) { println!(..); } !!!

Ownership 16

Page 34: Rust Mozlando Tutorial

fn main() { let name = format!(“…”); helper(name); helper(name); }

fn helper(name: String) { println!(..); } !!!

Ownership 16

Page 35: Rust Mozlando Tutorial

fn main() { let name = format!(“…”); helper(name); helper(name); }

fn helper(name: String) { println!(..); } !!!

Ownership 16

Error: use of moved value: `name`

Page 36: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

Page 37: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

Page 38: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java

Take reference to Vector

17

Page 39: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

Page 40: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

Page 41: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

Page 42: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

Page 43: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

Page 44: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

Page 45: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

Page 46: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

Page 47: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

Page 48: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

new Thread(…);

Page 49: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

new Thread(…);

Page 50: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

new Thread(…);

Page 51: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

new Thread(…);

Page 52: Rust Mozlando Tutorial

void main() { Vector name = …; helper(name); helper(name); }

void helper(Vector name) { … } !!!

“Ownership” in Java 17

new Thread(…);

Page 53: Rust Mozlando Tutorial

Clone

18

fn main() { let name = format!(“…”); helper(name.clone()); helper(name); }

fn helper(name: String) { println!(..); } !!!

Page 54: Rust Mozlando Tutorial

Clone

18

fn main() { let name = format!(“…”); helper(name.clone()); helper(name); }

fn helper(name: String) { println!(..); } !!!

Page 55: Rust Mozlando Tutorial

Clone

18

fn main() { let name = format!(“…”); helper(name.clone()); helper(name); }

fn helper(name: String) { println!(..); } !!!Copy the String

Page 56: Rust Mozlando Tutorial

Clone

18

fn main() { let name = format!(“…”); helper(name.clone()); helper(name); }

fn helper(name: String) { println!(..); } !!!

Page 57: Rust Mozlando Tutorial

Clone

18

fn main() { let name = format!(“…”); helper(name.clone()); helper(name); }

fn helper(name: String) { println!(..); } !!!

Page 58: Rust Mozlando Tutorial

Clone

18

fn main() { let name = format!(“…”); helper(name.clone()); helper(name); }

fn helper(name: String) { println!(..); } !!!

Page 59: Rust Mozlando Tutorial

Clone

18

fn main() { let name = format!(“…”); helper(name.clone()); helper(name); }

fn helper(name: String) { println!(..); } !!!

Page 60: Rust Mozlando Tutorial

Clone

18

fn main() { let name = format!(“…”); helper(name.clone()); helper(name); }

fn helper(name: String) { println!(..); } !!!

Page 61: Rust Mozlando Tutorial

Clone

18

fn main() { let name = format!(“…”); helper(name.clone()); helper(name); }

fn helper(name: String) { println!(..); } !!!

Page 62: Rust Mozlando Tutorial

Copy (auto-Clone)

19

fn main() { let name = 22; helper(name); helper(name); }

fn helper(name: i32) { println!(..); } !!!

Page 63: Rust Mozlando Tutorial

Copy (auto-Clone)

19

fn main() { let name = 22; helper(name); helper(name); }

fn helper(name: i32) { println!(..); } !!!

i32 is a Copy type

Page 64: Rust Mozlando Tutorial

Copy (auto-Clone)

19

fn main() { let name = 22; helper(name); helper(name); }

fn helper(name: i32) { println!(..); } !!!

i32 is a Copy type

Page 65: Rust Mozlando Tutorial

Copy (auto-Clone)

19

fn main() { let name = 22; helper(name); helper(name); }

fn helper(name: i32) { println!(..); } !!!

i32 is a Copy type

Page 66: Rust Mozlando Tutorial

Copy (auto-Clone)

19

fn main() { let name = 22; helper(name); helper(name); }

fn helper(name: i32) { println!(..); } !!!

i32 is a Copy type

Page 67: Rust Mozlando Tutorial

Copy (auto-Clone)

19

fn main() { let name = 22; helper(name); helper(name); }

fn helper(name: i32) { println!(..); } !!!

i32 is a Copy type

Page 68: Rust Mozlando Tutorial

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).

Page 69: Rust Mozlando Tutorial

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

Page 70: Rust Mozlando Tutorial

Borrowing22

Page 71: Rust Mozlando Tutorial

Borrowing22

Page 72: Rust Mozlando Tutorial

Borrowing22

Page 73: Rust Mozlando Tutorial

fn helper(name: &String) { println!(..); } !!!

fn main() { let name = format!(“…”); helper(&name); helper(&name); }

Shared borrow 23

Page 74: Rust Mozlando Tutorial

fn helper(name: &String) { println!(..); } !!!

fn main() { let name = format!(“…”); helper(&name); helper(&name); }

Shared borrow 23

Page 75: Rust Mozlando Tutorial

fn helper(name: &String) { println!(..); } !!!

fn main() { let name = format!(“…”); helper(&name); helper(&name); }

Shared borrow 23

Page 76: Rust Mozlando Tutorial

fn helper(name: &String) { println!(..); } !!!

fn main() { let name = format!(“…”); helper(&name); helper(&name); }

Shared borrow

Take a reference to a String

23

Page 77: Rust Mozlando Tutorial

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

Page 78: Rust Mozlando Tutorial

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

Page 79: Rust Mozlando Tutorial

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

Page 80: Rust Mozlando Tutorial

fn helper(name: &String) { println!(..); } !!!

fn main() { let name = format!(“…”); helper(&name); helper(&name); }

Shared borrow 23

Page 81: Rust Mozlando Tutorial

fn helper(name: &String) { println!(..); } !!!

fn main() { let name = format!(“…”); helper(&name); helper(&name); }

Shared borrow 23

Page 82: Rust Mozlando Tutorial

fn helper(name: &String) { println!(..); } !!!

fn main() { let name = format!(“…”); helper(&name); helper(&name); }

Shared borrow 23

Page 83: Rust Mozlando Tutorial

fn helper(name: &String) { println!(..); } !!!

fn main() { let name = format!(“…”); helper(&name); helper(&name); }

Shared borrow 23

Page 84: Rust Mozlando Tutorial

fn helper(name: &String) { println!(..); } !!!

fn main() { let name = format!(“…”); helper(&name); helper(&name); }

Shared borrow 23

Page 85: Rust Mozlando Tutorial

fn helper(name: &String) { println!(..); } !!!

fn main() { let name = format!(“…”); helper(&name); helper(&name); }

Shared borrow 23

Page 86: Rust Mozlando Tutorial

fn helper(name: &String) { println!(..); } !!!

fn main() { let name = format!(“…”); helper(&name); helper(&name); }

Shared borrow 23

Page 87: Rust Mozlando Tutorial

Shared == Immutable

24

fn helper(name: &String) { println!(“{}”, name); }

fn helper(name: &String) { name.push_str(“foo”); }

Page 88: Rust Mozlando Tutorial

Shared == Immutable

24

fn helper(name: &String) { println!(“{}”, name); }

fn helper(name: &String) { name.push_str(“foo”); }

OK. Just reads.

Page 89: Rust Mozlando Tutorial

Shared == Immutable

24

fn helper(name: &String) { println!(“{}”, name); }

fn helper(name: &String) { name.push_str(“foo”); }

OK. Just reads.

Error. Writes.

Page 90: Rust Mozlando Tutorial

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”); ^~~~

Page 91: Rust Mozlando Tutorial

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”); ^~~~

Page 92: Rust Mozlando Tutorial

fn update(name: &mut String) { name.push_str(“…”); } !!!

fn main() { let mut name = …; update(&mut name); println!(“{}”, name); }

Mutable borrow 25

Page 93: Rust Mozlando Tutorial

fn update(name: &mut String) { name.push_str(“…”); } !!!

fn main() { let mut name = …; update(&mut name); println!(“{}”, name); }

Mutable borrow 25

Page 94: Rust Mozlando Tutorial

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

Page 95: Rust Mozlando Tutorial

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

Page 96: Rust Mozlando Tutorial

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

Page 97: Rust Mozlando Tutorial

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

Page 98: Rust Mozlando Tutorial

fn update(name: &mut String) { name.push_str(“…”); } !!!

fn main() { let mut name = …; update(&mut name); println!(“{}”, name); }

Mutable borrow 25

Page 99: Rust Mozlando Tutorial

fn update(name: &mut String) { name.push_str(“…”); } !!!

fn main() { let mut name = …; update(&mut name); println!(“{}”, name); }

Mutable borrow 25

Page 100: Rust Mozlando Tutorial

fn update(name: &mut String) { name.push_str(“…”); } !!!

fn main() { let mut name = …; update(&mut name); println!(“{}”, name); }

Mutable borrow 25

Page 101: Rust Mozlando Tutorial

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

Page 102: Rust Mozlando Tutorial

fn update(name: &mut String) { name.push_str(“…”); } !!!

fn main() { let mut name = …; update(&mut name); println!(“{}”, name); }

Mutable borrow 25

Page 103: Rust Mozlando Tutorial

fn update(name: &mut String) { name.push_str(“…”); } !!!

fn main() { let mut name = …; update(&mut name); println!(“{}”, name); }

Mutable borrow 25

Page 104: Rust Mozlando Tutorial

fn update(name: &mut String) { name.push_str(“…”); } !!!

fn main() { let mut name = …; update(&mut name); println!(“{}”, name); }

Mutable borrow 25

Page 105: Rust Mozlando Tutorial

fn update(name: &mut String) { name.push_str(“…”); } !!!

fn main() { let mut name = …; update(&mut name); println!(“{}”, name); }

Mutable borrow 25

Page 106: Rust Mozlando Tutorial

fn update(name: &mut String) { name.push_str(“…”); } !!!

fn main() { let mut name = …; update(&mut name); println!(“{}”, name); }

Mutable borrow 25

Page 107: Rust Mozlando Tutorial

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.

Page 108: Rust Mozlando Tutorial

fn update(name: &mut String) { name.push_str(“…”); } !!!

fn main() { let mut name = …; update(&mut name); println!(“{}”, name); }

Mutable borrow 25

Page 109: Rust Mozlando Tutorial

fn update(name: &mut String) { name.push_str(“…”); } !!!

fn main() { let mut name = …; update(&mut name); println!(“{}”, name); }

Mutable borrow 25

Page 110: Rust Mozlando Tutorial

fn update(name: &mut String) { name.push_str(“…”); } !!!

fn main() { let mut name = …; update(&mut name); println!(“{}”, name); }

Mutable borrow 25

Page 111: Rust Mozlando Tutorial

Play time

26http://is.gd/no0tTH

Page 112: Rust Mozlando Tutorial

.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’

Page 113: Rust Mozlando Tutorial

.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’

Page 114: Rust Mozlando Tutorial

.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’

Page 115: Rust Mozlando Tutorial

.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’

Page 116: Rust Mozlando Tutorial

.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”

Page 117: Rust Mozlando Tutorial

.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”

Page 118: Rust Mozlando Tutorial

.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”

Page 119: Rust Mozlando Tutorial

.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”

Page 120: Rust Mozlando Tutorial

.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

Page 121: Rust Mozlando Tutorial

.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”

Page 122: Rust Mozlando Tutorial

.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..]);

Page 123: Rust Mozlando Tutorial

.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

Page 124: Rust Mozlando Tutorial

.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

Page 125: Rust Mozlando Tutorial

.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

Page 126: Rust Mozlando Tutorial

.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

Page 127: Rust Mozlando Tutorial

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…

Page 128: Rust Mozlando Tutorial

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…

Page 129: Rust Mozlando Tutorial

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…

Page 130: Rust Mozlando Tutorial

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…

Page 131: Rust Mozlando Tutorial

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…

Page 132: Rust Mozlando Tutorial

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

Page 133: Rust Mozlando Tutorial

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

Page 134: Rust Mozlando Tutorial

Whither Safety?

30https://www.flickr.com/photos/langtind/2217639550/in/photostream/

Page 135: Rust Mozlando Tutorial

GC vs C++ vs Rust

31

GC’d language (e.g. Java)One size fits all`void helper(String name)`

temporary access?start a thread?store in a static?

RustTemporary references — confined to owner’s scopeData cannot be freed or mutated while reference is live

C++No clear rulesEasily invalidated“Don’t make mistakes”

Page 136: Rust Mozlando Tutorial

GC vs C++ vs Rust

31

GC’d language (e.g. Java)One size fits all`void helper(String name)`

temporary access?start a thread?store in a static?

RustTemporary references — confined to owner’s scopeData cannot be freed or mutated while reference is live

C++No clear rulesEasily invalidated“Don’t make mistakes”

Page 137: Rust Mozlando Tutorial

GC vs C++ vs Rust

31

GC’d language (e.g. Java)One size fits all`void helper(String name)`

temporary access?start a thread?store in a static?

RustTemporary references — confined to owner’s scopeData cannot be freed or mutated while reference is live

C++No clear rulesEasily invalidated“Don’t make mistakes”

Page 138: Rust Mozlando Tutorial

GC vs C++ vs Rust

31

GC’d language (e.g. Java)One size fits all`void helper(String name)`

temporary access?start a thread?store in a static?

RustTemporary references — confined to owner’s scopeData cannot be freed or mutated while reference is live

C++No clear rulesEasily invalidated“Don’t make mistakes”

Page 139: Rust Mozlando Tutorial

GC vs C++ vs Rust

31

GC’d language (e.g. Java)One size fits all`void helper(String name)`

temporary access?start a thread?store in a static?

RustTemporary references — confined to owner’s scopeData cannot be freed or mutated while reference is live

C++No clear rulesEasily invalidated“Don’t make mistakes”

Page 140: Rust Mozlando Tutorial

GC vs C++ vs Rust

31

GC’d language (e.g. Java)One size fits all`void helper(String name)`

temporary access?start a thread?store in a static?

RustTemporary references — confined to owner’s scopeData cannot be freed or mutated while reference is live

C++No clear rulesEasily invalidated“Don’t make mistakes”

Page 141: Rust Mozlando Tutorial

GC vs C++ vs Rust

31

GC’d language (e.g. Java)One size fits all`void helper(String name)`

temporary access?start a thread?store in a static?

RustTemporary references — confined to owner’s scopeData cannot be freed or mutated while reference is live

C++No clear rulesEasily invalidated“Don’t make mistakes”

Page 142: Rust Mozlando Tutorial

GC vs C++ vs Rust

31

GC’d language (e.g. Java)One size fits all`void helper(String name)`

temporary access?start a thread?store in a static?

RustTemporary references — confined to owner’s scopeData cannot be freed or mutated while reference is live

C++No clear rulesEasily invalidated“Don’t make mistakes”

Page 143: Rust Mozlando Tutorial

GC vs C++ vs Rust

31

GC’d language (e.g. Java)One size fits all`void helper(String name)`

temporary access?start a thread?store in a static?

RustTemporary references — confined to owner’s scopeData cannot be freed or mutated while reference is live

C++No clear rulesEasily invalidated“Don’t make mistakes”

Page 144: Rust Mozlando Tutorial

GC vs C++ vs Rust

31

GC’d language (e.g. Java)One size fits all`void helper(String name)`

temporary access?start a thread?store in a static?

RustTemporary references — confined to owner’s scopeData cannot be freed or mutated while reference is live

C++No clear rulesEasily invalidated“Don’t make mistakes”

Page 145: Rust Mozlando Tutorial

GC vs C++ vs Rust

31

GC’d language (e.g. Java)One size fits all`void helper(String name)`

temporary access?start a thread?store in a static?

RustTemporary references — confined to owner’s scopeData cannot be freed or mutated while reference is live

C++No clear rulesEasily invalidated“Don’t make mistakes”

Page 146: Rust Mozlando Tutorial

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

Page 147: Rust Mozlando Tutorial

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

Page 148: Rust Mozlando Tutorial

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Page 149: Rust Mozlando Tutorial

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Page 150: Rust Mozlando Tutorial

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Page 151: Rust Mozlando Tutorial

.capacity: …

.len: 10

name.data ‘R’ ‘u’ … ‘n’ ‘s’

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Page 152: Rust Mozlando Tutorial

.capacity: …

.len: 10

name.data ‘R’ ‘u’ … ‘n’ ‘s’

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Page 153: Rust Mozlando Tutorial

.capacity: …

.len: 10

name.data ‘R’ ‘u’ … ‘n’ ‘s’

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Page 154: Rust Mozlando Tutorial

.capacity: …

.len: 10

name.data ‘R’ ‘u’ … ‘n’ ‘s’

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Page 155: Rust Mozlando Tutorial

.capacity: …

.len: 10

name.data ‘R’ ‘u’ … ‘n’ ‘s’

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Page 156: Rust Mozlando Tutorial

.capacity: …

.len: 10

name.data ‘R’ ‘u’ … ‘n’ ‘s’

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Page 157: Rust Mozlando Tutorial

.capacity: …

.len: 10

name.data ‘R’ ‘u’ … ‘n’ ‘s’

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Page 158: Rust Mozlando Tutorial

.capacity: …

.len: 10

name.data ‘R’ ‘u’ … ‘n’ ‘s’

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Page 159: Rust Mozlando Tutorial

.capacity: …

.len: 10

name.data ‘R’ ‘u’ … ‘n’ ‘s’

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Page 160: Rust Mozlando Tutorial

.capacity: …

.len: 10

name.data ‘R’ ‘u’ … ‘n’ ‘s’

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Dangling reference!

Page 161: Rust Mozlando Tutorial

.capacity: …

.len: 10

name.data ‘R’ ‘u’ … ‘n’ ‘s’

32

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

r

Dangling reference!

Page 162: Rust Mozlando Tutorial

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

33http://is.gd/HJyO7A

Page 163: Rust Mozlando Tutorial

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

33http://is.gd/HJyO7A

Page 164: Rust Mozlando Tutorial

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

33

Lifetime: span of code where reference is used.

http://is.gd/HJyO7A

Page 165: Rust Mozlando Tutorial

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

33

Lifetime: span of code where reference is used.

http://is.gd/HJyO7A

Page 166: Rust Mozlando Tutorial

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

33

Lifetime: span of code where reference is used.

http://is.gd/HJyO7A

Page 167: Rust Mozlando Tutorial

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

33

Lifetime: span of code where reference is used.

http://is.gd/HJyO7A

Page 168: Rust Mozlando Tutorial

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

33

Lifetime: span of code where reference is used.

http://is.gd/HJyO7A

Page 169: Rust Mozlando Tutorial

fn main() { let r; { let name = format!(“…”); r = &name; } println!(“{}”, r); }

33

Lifetime: span of code where reference is used.

http://is.gd/HJyO7A

Page 170: Rust Mozlando Tutorial

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

Page 171: Rust Mozlando Tutorial

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

Page 172: Rust Mozlando Tutorial

‘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

Page 173: Rust Mozlando Tutorial

‘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; ^~~~

Page 174: Rust Mozlando Tutorial

34

use std::thread; !fn helper(name: &String) { thread::spawn(move || { use(name); }); }

Page 175: Rust Mozlando Tutorial

34

use std::thread; !fn helper(name: &String) { thread::spawn(move || { use(name); }); }

`name` can only be used within this fn

Page 176: Rust Mozlando Tutorial

34

use std::thread; !fn helper(name: &String) { thread::spawn(move || { use(name); }); }

`name` can only be used within this fn

Page 177: Rust Mozlando Tutorial

34

use std::thread; !fn helper(name: &String) { thread::spawn(move || { use(name); }); }

`name` can only be used within this fn

Page 178: Rust Mozlando Tutorial

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!

Page 179: Rust Mozlando Tutorial

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

Page 180: Rust Mozlando Tutorial

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

Page 181: Rust Mozlando Tutorial

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

Page 182: Rust Mozlando Tutorial

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

Page 183: Rust Mozlando Tutorial

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

Page 184: Rust Mozlando Tutorial

Dangers of mutation

35

let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice);

Page 185: Rust Mozlando Tutorial

Dangers of mutation

35

let mut buffer: String = format!(“Rustacean”); let slice = &buffer[1..]; buffer.push_str(“s”); println!(“{:?}”, slice);

Page 186: Rust Mozlando Tutorial

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

Page 187: Rust Mozlando Tutorial

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

Page 188: Rust Mozlando Tutorial

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

Page 189: Rust Mozlando Tutorial

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

Page 190: Rust Mozlando Tutorial

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

Page 191: Rust Mozlando Tutorial

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

Page 192: Rust Mozlando Tutorial

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

Page 193: Rust Mozlando Tutorial

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’

Page 194: Rust Mozlando Tutorial

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’

Page 195: Rust Mozlando Tutorial

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’

Page 196: Rust Mozlando Tutorial

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’

Page 197: Rust Mozlando Tutorial

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!

Page 198: Rust Mozlando Tutorial

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!

Page 199: Rust Mozlando Tutorial

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.

Page 200: Rust Mozlando Tutorial

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

Page 201: Rust Mozlando Tutorial

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

Page 202: Rust Mozlando Tutorial

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

Page 203: Rust Mozlando Tutorial

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

Page 204: Rust Mozlando Tutorial

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

Page 205: Rust Mozlando Tutorial

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

Page 206: Rust Mozlando Tutorial

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

Page 207: Rust Mozlando Tutorial

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

Page 208: Rust Mozlando Tutorial

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

Page 209: Rust Mozlando Tutorial

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

Page 210: Rust Mozlando Tutorial

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

Page 211: Rust Mozlando Tutorial

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

Page 212: Rust Mozlando Tutorial

40

Structs and such

Page 213: Rust Mozlando Tutorial

41Shop till you drop!

By QuentinUK (Own work), via Wikimedia Commons

Page 214: Rust Mozlando Tutorial

Declaring a structure

42

struct Store { name: String, prices: Vec<Item>, }

Page 215: Rust Mozlando Tutorial

Declaring a structure

42

struct Store { name: String, prices: Vec<Item>, }

Page 216: Rust Mozlando Tutorial

Declaring a structure

42

struct Store { name: String, prices: Vec<Item>, }

Page 217: Rust Mozlando Tutorial

Declaring a structure

42

struct Store { name: String, prices: Vec<Item>, }

Page 218: Rust Mozlando Tutorial

Declaring a structure

42

struct Store { name: String, prices: Vec<Item>, }

Page 219: Rust Mozlando Tutorial

Declaring a structure

42

struct Store { name: String, prices: Vec<Item>, }

Page 220: Rust Mozlando Tutorial

Declaring a structure

42

struct Store { name: String, prices: Vec<Item>, }

Page 221: Rust Mozlando Tutorial

Declaring a structure

42

struct Store { name: String, prices: Vec<Item>, }

Page 222: Rust Mozlando Tutorial

Declaring a structure

42

struct Store { name: String, prices: Vec<Item>, }

Page 223: Rust Mozlando Tutorial

Declaring a structure

42

struct Store { name: String, prices: Vec<Item>, }

name

prices

Page 224: Rust Mozlando Tutorial

Declaring a structure

42

struct Store { name: String, prices: Vec<Item>, }

name

prices

.length

.data

.capacity

.length

.data

.capacity

Page 225: Rust Mozlando Tutorial

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

Page 226: Rust Mozlando Tutorial

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

Page 227: Rust Mozlando Tutorial

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] !!

floats signed unsigned slices

Page 228: Rust Mozlando Tutorial

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] !!

floats signed unsigned slices

Page 229: Rust Mozlando Tutorial

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] !!

floats signed unsigned slices

Page 230: Rust Mozlando Tutorial

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] !!

floats signed unsigned slices

Page 231: Rust Mozlando Tutorial

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] !!

floats signed unsigned slices

Page 232: Rust Mozlando Tutorial

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] !!

floats signed unsigned slices

Page 233: Rust Mozlando Tutorial

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] !!

floats signed unsigned slices

Page 234: Rust Mozlando Tutorial

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] !!

floats signed unsigned slices

Page 235: Rust Mozlando Tutorial

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] !!

floats signed unsigned slices

Page 236: Rust Mozlando Tutorial

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] !!

floats signed unsigned slices

Page 237: Rust Mozlando Tutorial

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] !!

floats signed unsigned slices

Page 238: Rust Mozlando Tutorial

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] !!

floats signed unsigned slices

Page 239: Rust Mozlando Tutorial

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] !!

floats signed unsigned slices

Page 240: Rust Mozlando Tutorial

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 } }

Page 241: Rust Mozlando Tutorial

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 } }

Page 242: Rust Mozlando Tutorial

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 } }

Page 243: Rust Mozlando Tutorial

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

Page 244: Rust Mozlando Tutorial

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

Page 245: Rust Mozlando Tutorial

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

Page 246: Rust Mozlando Tutorial

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

Page 247: Rust Mozlando Tutorial

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

Page 248: Rust Mozlando Tutorial

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

Page 249: Rust Mozlando Tutorial

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

Page 250: Rust Mozlando Tutorial

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

Page 251: Rust Mozlando Tutorial

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

Page 252: Rust Mozlando Tutorial

Methods

45

struct Store { .. } !impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }

Page 253: Rust Mozlando Tutorial

Methods

45

struct Store { .. } !impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }

Page 254: Rust Mozlando Tutorial

Methods

45

struct Store { .. } !impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }

Store::new(some_name)

Page 255: Rust Mozlando Tutorial

Methods

45

struct Store { .. } !impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }

Store::new(some_name)

Page 256: Rust Mozlando Tutorial

Methods

45

struct Store { .. } !impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }

Store::new(some_name)

Page 257: Rust Mozlando Tutorial

Methods

45

struct Store { .. } !impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }

Store::new(some_name)

Page 258: Rust Mozlando Tutorial

Methods

45

struct Store { .. } !impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }

Store::new(some_name)

Page 259: Rust Mozlando Tutorial

Methods

45

struct Store { .. } !impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }

Store::new(some_name)

Page 260: Rust Mozlando Tutorial

Methods

45

struct Store { .. } !impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }

Store::new(some_name)

Page 261: Rust Mozlando Tutorial

Methods

45

struct Store { .. } !impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }

Store::new(some_name)

Page 262: Rust Mozlando Tutorial

Methods

45

struct Store { .. } !impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }

Store::new(some_name)

Page 263: Rust Mozlando Tutorial

Methods

45

struct Store { .. } !impl Store { fn new(name: String) -> Store { return Store { name: name, items: vec![], }; } }

Store::new(some_name)

Page 264: Rust Mozlando Tutorial

Return is optional

46

struct Store { .. } !impl Store { fn new(name: String) -> Store { Store { name: name, items: vec![], } } }

Page 265: Rust Mozlando Tutorial

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”

Page 266: Rust Mozlando Tutorial

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

Page 267: Rust Mozlando Tutorial

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

Page 268: Rust Mozlando Tutorial

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

Page 269: Rust Mozlando Tutorial

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

Page 270: Rust Mozlando Tutorial

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

Page 271: Rust Mozlando Tutorial

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

Page 272: Rust Mozlando Tutorial

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

Page 273: Rust Mozlando Tutorial

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

Page 274: Rust Mozlando Tutorial

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

Page 275: Rust Mozlando Tutorial

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

Page 276: Rust Mozlando Tutorial

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

Page 277: Rust Mozlando Tutorial

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:

Page 278: Rust Mozlando Tutorial

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:

Page 279: Rust Mozlando Tutorial

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:

Page 280: Rust Mozlando Tutorial

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:

Page 281: Rust Mozlando Tutorial

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>

Page 282: Rust Mozlando Tutorial

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>

Page 283: Rust Mozlando Tutorial

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:

Page 284: Rust Mozlando Tutorial

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:

Page 285: Rust Mozlando Tutorial

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:

Page 286: Rust Mozlando Tutorial

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:

Page 287: Rust Mozlando Tutorial

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:

Page 288: Rust Mozlando Tutorial

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:

Page 289: Rust Mozlando Tutorial

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:

Page 290: Rust Mozlando Tutorial

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>

Page 291: Rust Mozlando Tutorial

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>

Page 292: Rust Mozlando Tutorial

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:

Page 293: Rust Mozlando Tutorial

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:

Page 294: Rust Mozlando Tutorial

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:

Page 295: Rust Mozlando Tutorial

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:

Page 296: Rust Mozlando Tutorial

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

Page 297: Rust Mozlando Tutorial

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:

Page 298: Rust Mozlando Tutorial

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

Page 299: Rust Mozlando Tutorial

51

Threading

Page 300: Rust Mozlando Tutorial

Multiparadigm

52

Multiparadigm

Page 301: Rust Mozlando Tutorial

Multiparadigm

52

Multiparadigm

message-passing

Page 302: Rust Mozlando Tutorial

Multiparadigm

52

Multiparadigm

mutable shared memorymessage-passing

Page 303: Rust Mozlando Tutorial

53

Page 304: Rust Mozlando Tutorial

53

$5.0 $25.5 $81.5 ——— $112.0

Page 305: Rust Mozlando Tutorial

53

$5.0 $25.5 $81.5 ——— $112.0

$5.0 $20.5 $81.5 ——— $107.0

Page 306: Rust Mozlando Tutorial

53

$5.0 $25.5 $81.5 ——— $112.0

$5.0 $20.5 $81.5 ——— $107.0

$5.0 $23.5

XXX ——— XXX

Page 307: Rust Mozlando Tutorial

53

$5.0 $25.5 $81.5 ——— $112.0

$5.0 $20.5 $81.5 ——— $107.0

$5.0 $23.5

XXX ——— XXX

Page 308: Rust Mozlando Tutorial

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; } _ => { } } }

Page 309: Rust Mozlando Tutorial

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; } _ => { } } }

Page 310: Rust Mozlando Tutorial

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; } _ => { } } }

Page 311: Rust Mozlando Tutorial

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; } _ => { } } }

Page 312: Rust Mozlando Tutorial

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; } _ => { } } }

Page 313: Rust Mozlando Tutorial

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; } _ => { } } }

Page 314: Rust Mozlando Tutorial

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; } _ => { } } }

Page 315: Rust Mozlando Tutorial

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; } _ => { } } }

Page 316: Rust Mozlando Tutorial

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; } _ => { } } }

Page 317: Rust Mozlando Tutorial

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; } _ => { } } }

Page 318: Rust Mozlando Tutorial

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; } _ => { } } }

Page 319: Rust Mozlando Tutorial

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; } _ => { } } }

Page 320: Rust Mozlando Tutorial

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; } _ => { } } }

Page 321: Rust Mozlando Tutorial

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; } _ => { } } }

Page 322: Rust Mozlando Tutorial

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; } _ => { } } }

Page 323: Rust Mozlando Tutorial

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; } _ => { } } }

Page 324: Rust Mozlando Tutorial

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

Page 325: Rust Mozlando Tutorial

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

Page 326: Rust Mozlando Tutorial

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

Page 327: Rust Mozlando Tutorial

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

Page 328: Rust Mozlando Tutorial

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

Page 329: Rust Mozlando Tutorial

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

Page 330: Rust Mozlando Tutorial

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

Page 331: Rust Mozlando Tutorial

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

Page 332: Rust Mozlando Tutorial

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

Page 333: Rust Mozlando Tutorial

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

Page 334: Rust Mozlando Tutorial

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

Page 335: Rust Mozlando Tutorial

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.

Page 336: Rust Mozlando Tutorial

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.

Page 337: Rust Mozlando Tutorial

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.

Page 338: Rust Mozlando Tutorial

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

Page 339: Rust Mozlando Tutorial

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.

Page 340: Rust Mozlando Tutorial

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

Page 341: Rust Mozlando Tutorial

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

Page 342: Rust Mozlando Tutorial

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

Page 343: Rust Mozlando Tutorial

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

Page 344: Rust Mozlando Tutorial

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

Page 345: Rust Mozlando Tutorial

57

let handle = thread::spawn(…);

Page 346: Rust Mozlando Tutorial

57

let handle = thread::spawn(…);

Page 347: Rust Mozlando Tutorial

57

let handle = thread::spawn(…);

… // stuff in parallel // with new thread

Page 348: Rust Mozlando Tutorial

57

let handle = thread::spawn(…);

… // stuff in parallel // with new thread

let (name, sum) = handle.join().unwrap();

Page 349: Rust Mozlando Tutorial

57

let handle = thread::spawn(…);

… // stuff in parallel // with new thread

let (name, sum) = handle.join().unwrap();

Page 350: Rust Mozlando Tutorial

57

let handle = thread::spawn(…);

… // stuff in parallel // with new thread

let (name, sum) = handle.join().unwrap();

Wait for thread to finish and

get return value.

Page 351: Rust Mozlando Tutorial

57

let handle = thread::spawn(…);

… // stuff in parallel // with new thread

let (name, sum) = handle.join().unwrap();

Wait for thread to finish and

get return value.

Result<(String, f32), Error>

Page 352: Rust Mozlando Tutorial

57

let handle = thread::spawn(…);

… // stuff in parallel // with new thread

let (name, sum) = handle.join().unwrap();

Wait for thread to finish and

get return value.

Thread may have panicked. Propagate.

Page 353: Rust Mozlando Tutorial

57

let handle = thread::spawn(…);

… // stuff in parallel // with new thread

let (name, sum) = handle.join().unwrap();

Wait for thread to finish and

get return value.

Thread may have panicked. Propagate.Result of thread.

Page 354: Rust Mozlando Tutorial

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 }

Page 355: Rust Mozlando Tutorial

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 }

Page 356: Rust Mozlando Tutorial

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 }

Page 357: Rust Mozlando Tutorial

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 }

Page 358: Rust Mozlando Tutorial

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 }

Page 359: Rust Mozlando Tutorial

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 }

Page 360: Rust Mozlando Tutorial

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 }

Page 361: Rust Mozlando Tutorial

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 }

Page 362: Rust Mozlando Tutorial

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 }

Page 363: Rust Mozlando Tutorial

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 }

Page 364: Rust Mozlando Tutorial

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 }

Page 365: Rust Mozlando Tutorial

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 }

Page 366: Rust Mozlando Tutorial

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 }

Page 367: Rust Mozlando Tutorial

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 }

Page 368: Rust Mozlando Tutorial

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 }

Page 369: Rust Mozlando Tutorial

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); }

Page 370: Rust Mozlando Tutorial

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.

Page 371: Rust Mozlando Tutorial

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); }

Page 372: Rust Mozlando Tutorial

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); }

Page 373: Rust Mozlando Tutorial

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); }

Page 374: Rust Mozlando Tutorial

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); }

Page 375: Rust Mozlando Tutorial

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()`?

Page 376: Rust Mozlando Tutorial

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()`?

Page 377: Rust Mozlando Tutorial

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); }

Page 378: Rust Mozlando Tutorial

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); }

Page 379: Rust Mozlando Tutorial

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); }

Page 380: Rust Mozlando Tutorial

61

use std::sync::Arc; let shopping_list: Vec<ShoppingList> = …; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];

Page 381: Rust Mozlando Tutorial

61

use std::sync::Arc; let shopping_list: Vec<ShoppingList> = …; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];

Page 382: Rust Mozlando Tutorial

61

use std::sync::Arc; let shopping_list: Vec<ShoppingList> = …; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];

Page 383: Rust Mozlando Tutorial

61

use std::sync::Arc; let shopping_list: Vec<ShoppingList> = …; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];

Page 384: Rust Mozlando Tutorial

61

use std::sync::Arc; let shopping_list: Vec<ShoppingList> = …; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];

Page 385: Rust Mozlando Tutorial

61

use std::sync::Arc; let shopping_list: Vec<ShoppingList> = …; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];

Page 386: Rust Mozlando Tutorial

61

use std::sync::Arc; let shopping_list: Vec<ShoppingList> = …; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];

Page 387: Rust Mozlando Tutorial

61

use std::sync::Arc; let shopping_list: Vec<ShoppingList> = …; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];

Page 388: Rust Mozlando Tutorial

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

Page 389: Rust Mozlando Tutorial

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

Page 390: Rust Mozlando Tutorial

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

Page 391: Rust Mozlando Tutorial

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

Page 392: Rust Mozlando Tutorial

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

Page 393: Rust Mozlando Tutorial

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

Page 394: Rust Mozlando Tutorial

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

Page 395: Rust Mozlando Tutorial

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

Page 396: Rust Mozlando Tutorial

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

Page 397: Rust Mozlando Tutorial

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

Page 398: Rust Mozlando Tutorial

61

use std::sync::Arc; let shopping_list: Vec<ShoppingList> = …; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];

Page 399: Rust Mozlando Tutorial

61

use std::sync::Arc; let shopping_list: Vec<ShoppingList> = …; let arc1 = Arc::new(shopping_list); let arc2 = arc1.clone(); let data = &arc1[0];

Page 400: Rust Mozlando Tutorial

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

Page 401: Rust Mozlando Tutorial

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

Page 402: Rust Mozlando Tutorial

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

Page 403: Rust Mozlando Tutorial

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); }

Page 404: Rust Mozlando Tutorial

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); }

Page 405: Rust Mozlando Tutorial

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); }

Page 406: Rust Mozlando Tutorial

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); }

Page 407: Rust Mozlando Tutorial

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); }

Page 408: Rust Mozlando Tutorial

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); }

Page 409: Rust Mozlando Tutorial

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); }

Page 410: Rust Mozlando Tutorial

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); }

Page 411: Rust Mozlando Tutorial

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); }

Page 412: Rust Mozlando Tutorial

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); }

Page 413: Rust Mozlando Tutorial

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); }

Page 414: Rust Mozlando Tutorial

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); }

Page 415: Rust Mozlando Tutorial

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); }

Page 416: Rust Mozlando Tutorial

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); }

Page 417: Rust Mozlando Tutorial

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); }

Page 418: Rust Mozlando Tutorial

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); }

Page 419: Rust Mozlando Tutorial

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); }

Page 420: Rust Mozlando Tutorial

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); }

Page 421: Rust Mozlando Tutorial

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!

Page 422: Rust Mozlando Tutorial

Channels

64

Page 423: Rust Mozlando Tutorial

65

Joining a thread allows thread to send one result.

What if we wanted multiple results?

Page 424: Rust Mozlando Tutorial

65

Joining a thread allows thread to send one result.

What if we wanted multiple results?

Page 425: Rust Mozlando Tutorial

65

Joining a thread allows thread to send one result.

What if we wanted multiple results?

Page 426: Rust Mozlando Tutorial

65

Joining a thread allows thread to send one result.

What if we wanted multiple results?

Page 427: Rust Mozlando Tutorial

65

Joining a thread allows thread to send one result.

What if we wanted multiple results?

Page 428: Rust Mozlando Tutorial

65

Joining a thread allows thread to send one result.

What if we wanted multiple results?

Page 429: Rust Mozlando Tutorial

65

Joining a thread allows thread to send one result.

What if we wanted multiple results?

Or if we wanted a response?

Page 430: Rust Mozlando Tutorial

65

Joining a thread allows thread to send one result.

What if we wanted multiple results?

Or if we wanted a response?

Page 431: Rust Mozlando Tutorial

fn parent() { let (tx, rx) = channel(); spawn(move || {…}); let m = rx.recv().unwrap(); }

66

Page 432: Rust Mozlando Tutorial

rx

tx

fn parent() { let (tx, rx) = channel(); spawn(move || {…}); let m = rx.recv().unwrap(); }

66

Page 433: Rust Mozlando Tutorial

rx

tx

fn parent() { let (tx, rx) = channel(); spawn(move || {…}); let m = rx.recv().unwrap(); }

66

Page 434: Rust Mozlando Tutorial

rx

tx

fn parent() { let (tx, rx) = channel(); spawn(move || {…}); let m = rx.recv().unwrap(); }

66

Page 435: Rust Mozlando Tutorial

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(); }

Page 436: Rust Mozlando Tutorial

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(); }

Page 437: Rust Mozlando Tutorial

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(); }

Page 438: Rust Mozlando Tutorial

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(); }

Page 439: Rust Mozlando Tutorial

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(); }

Page 440: Rust Mozlando Tutorial

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(); }

Page 441: Rust Mozlando Tutorial

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(); }

Page 442: Rust Mozlando Tutorial

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(); }

Page 443: Rust Mozlando Tutorial

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(); }

Page 444: Rust Mozlando Tutorial

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(); }

Page 445: Rust Mozlando Tutorial

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(); }

Page 446: Rust Mozlando Tutorial

67

rx0

tx0

let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);

Page 447: Rust Mozlando Tutorial

67

rx0

tx0

let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);

Page 448: Rust Mozlando Tutorial

67

rx0

tx0

let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);

tx1

Page 449: Rust Mozlando Tutorial

67

rx0

tx0

let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);

tx1

Page 450: Rust Mozlando Tutorial

67

rx0

tx0

let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);

tx1

Page 451: Rust Mozlando Tutorial

67

rx0

tx0

let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);

tx1

Page 452: Rust Mozlando Tutorial

67

rx0

tx0

let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);

tx1

tx2

Page 453: Rust Mozlando Tutorial

67

rx0

tx0

let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);

tx1

tx2

Page 454: Rust Mozlando Tutorial

67

rx0

tx0

let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);

tx1

tx2

Page 455: Rust Mozlando Tutorial

67

rx0

tx0

let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);

tx1

tx2

Page 456: Rust Mozlando Tutorial

67

rx0

tx0

let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);

tx1

tx2

Page 457: Rust Mozlando Tutorial

67

rx0

tx0

let (tx0, rx0) = channel(); let tx1 = tx0.clone(); spawn(move || /* omitted */); let tx2 = tx0.clone(); spawn(move || /* omitted */);

tx1

tx2

Page 458: Rust Mozlando Tutorial

Locks

68

Page 459: Rust Mozlando Tutorial

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

Page 460: Rust Mozlando Tutorial

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

Page 461: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

Page 462: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

Page 463: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

Page 464: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

data

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

Page 465: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

data

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

Page 466: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

data

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

Page 467: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

data

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

1

Page 468: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

data

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

1

Page 469: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

data

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

1

Page 470: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

1

Page 471: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

1

Page 472: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

1

Page 473: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

1

Page 474: Rust Mozlando Tutorial

0

69

fn sync_inc(counter: &Arc<Mutex<i32>>) { let mut data = counter.lock().unwrap(); *data += 1; }

counter

https://commons.wikimedia.org/wiki/File:No-DRM_lock.svg

1

Page 475: Rust Mozlando Tutorial

Exercise: threads

70

http://smallcultfollowing.com/20151209

Cheat sheet:let (name, sum) = thread.join().unwrap();

http://doc.rust-lang.org/std

use std::sync::mpsc::channel; let (rx, tx) = channel(); tx.send(value).unwrap(); let value = rx.recv().unwrap();

use std::sync::{Arc, Mutex}; let mutex = Arc::new(Mutex::new(data)); let data = mutex.lock().unwrap();

Page 476: Rust Mozlando Tutorial

Plea for help

71

Please fill out the feedback form found at

http://smallcultfollowing.com/20151209

Page 477: Rust Mozlando Tutorial

72

Page 478: Rust Mozlando Tutorial

72

Thanks for

listenin

g!