5. // sums all the positive values in `v`
fn sum_pos(v: &[i32]) -> i32 {
let mut sum = 0;
for i in v.iter().filter(|i| **i > 0) {
sum += *i;
}
sum
}
High-level coding
3
6. // sums all the positive values in `v`
fn sum_pos(v: &[i32]) -> i32 {
let mut sum = 0;
for i in v.iter().filter(|i| **i > 0) {
sum += *i;
}
sum
}
High-level coding
3
Iterators.
Closures.
10. Safe
6
fn this_wont_compile(v: &mut Vec<i32>) -> i32 {
let mut sum = 0;
for &i in v.iter() {
sum += i;
if i > 0 { v.push(0); }
}
sum
}
Might free
underlying buffer.
11. Safe
6
fn this_wont_compile(v: &mut Vec<i32>) -> i32 {
let mut sum = 0;
for &i in v.iter() {
sum += i;
if i > 0 { v.push(0); }
}
sum
}
error: cannot borrow `*v` as mutable because it is also borrowed
as immutable
if i > 0 { v.push(0); }
^
note: previous borrow of `*v` occurs here; the immutable borrow
prevents subsequent moves or mutable borrows of `*v` until
the borrow ends
for &i in v.iter() {
^
Might free
underlying buffer.
12. fn parallel_qsort(vec: &mut [int]) {
if vec.len() <= 1 { return; }
let pivot = vec[random(vec.len())];
let mid = vec.partition(vec, pivot);
let (less, greater) = vec.split_at_mut(mid);
rayon::join(
|| parallel_qsort(less),
|| parallel_qsort(greater)
);
}
Parallel
7Caveat: shameless plug for third-party package of mine.
13. fn parallel_qsort(vec: &mut [int]) {
if vec.len() <= 1 { return; }
let pivot = vec[random(vec.len())];
let mid = vec.partition(vec, pivot);
let (less, greater) = vec.split_at_mut(mid);
rayon::join(
|| parallel_qsort(less),
|| parallel_qsort(greater)
);
}
Parallel
7
Sort left and right
in parallel.Caveat: shameless plug for third-party package of mine.
14. fn parallel_qsort(vec: &mut [int]) {
if vec.len() <= 1 { return; }
let pivot = vec[random(vec.len())];
let mid = vec.partition(vec, pivot);
let (less, greater) = vec.split_at_mut(mid);
rayon::join(
|| parallel_qsort(less),
|| parallel_qsort(less)
);
}
Parallel… and safe
8
Data race.
15. fn parallel_qsort(vec: &mut [int]) {
if vec.len() <= 1 { return; }
let pivot = vec[random(vec.len())];
let mid = vec.partition(vec, pivot);
let (less, greater) = vec.split_at_mut(mid);
rayon::join(
|| parallel_qsort(less),
|| parallel_qsort(less)
);
}
Parallel… and safe
8
error: closure requires unique access to `less`
but it is already borrowed
|| parallel_qsort(less)
^~~~~~~~~~~~~~~~~~~~~~~
Data race.
16. Open and welcoming
Rust has been open source from the beginning.
!
Open governance model based on public RFCs.
!
We have an active, amazing community.
❤
9
63. Copy (auto-Clone)
19
fn main() {
let name = 22;
helper(name);
helper(name);
}
fn helper(name: i32) {
println!(..);
}
!
!
!
i32 is a Copy type
64. Copy (auto-Clone)
19
fn main() {
let name = 22;
helper(name);
helper(name);
}
fn helper(name: i32) {
println!(..);
}
!
!
!
i32 is a Copy type
65. Copy (auto-Clone)
19
fn main() {
let name = 22;
helper(name);
helper(name);
}
fn helper(name: i32) {
println!(..);
}
!
!
!
i32 is a Copy type
66. Copy (auto-Clone)
19
fn main() {
let name = 22;
helper(name);
helper(name);
}
fn helper(name: i32) {
println!(..);
}
!
!
!
i32 is a Copy type
67. Copy (auto-Clone)
19
fn main() {
let name = 22;
helper(name);
helper(name);
}
fn helper(name: i32) {
println!(..);
}
!
!
!
i32 is a Copy type
68. 20
Non-copyable: Values move from place to place.
Examples: File descriptor, database handle.
!
Clone: Run custom code to make a copy.
Examples: String, Vector!
!
Copy: Type is implicitly copied when referenced.
Examples: u32, i32, (f32, i32).
76. fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“…”);
helper(&name);
helper(&name);
}
Shared borrow
Take a reference
to a String
23
77. fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“…”);
helper(&name);
helper(&name);
}
Shared borrow
Take a reference
to a String
23
Lend the string
78. fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“…”);
helper(&name);
helper(&name);
}
Shared borrow
Take a reference
to a String
23
Lend the string
79. fn helper(name: &String) {
println!(..);
}
!
!
!
fn main() {
let name = format!(“…”);
helper(&name);
helper(&name);
}
Shared borrow
Take a reference
to a String
23
Lend the string
135. 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?
Rust
Temporary references — confined to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
136. GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size fits all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — confined to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
137. GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size fits all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — confined to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
138. GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size fits all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — confined to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
139. GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size fits all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — confined to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
140. GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size fits all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — confined to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
141. GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size fits all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — confined to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
142. GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size fits all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — confined to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
143. GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size fits all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — confined to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
144. GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size fits all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — confined to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
145. GC vs C++ vs Rust
31
GC’d language (e.g. Java)
One size fits all
`void helper(String name)`
temporary access?
start a thread?
store in a static?
Rust
Temporary references — confined to owner’s scope
Data cannot be freed or mutated while reference is live
C++
No clear rules
Easily invalidated
“Don’t make mistakes”
146. 32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
147. 32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
148. 32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
149. 32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
150. 32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
151. .capacity: …
.len: 10
name.data ‘R’ ‘u’ … ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
152. .capacity: …
.len: 10
name.data ‘R’ ‘u’ … ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
153. .capacity: …
.len: 10
name.data ‘R’ ‘u’ … ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
154. .capacity: …
.len: 10
name.data ‘R’ ‘u’ … ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
155. .capacity: …
.len: 10
name.data ‘R’ ‘u’ … ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
156. .capacity: …
.len: 10
name.data ‘R’ ‘u’ … ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
157. .capacity: …
.len: 10
name.data ‘R’ ‘u’ … ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
158. .capacity: …
.len: 10
name.data ‘R’ ‘u’ … ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
159. .capacity: …
.len: 10
name.data ‘R’ ‘u’ … ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
160. .capacity: …
.len: 10
name.data ‘R’ ‘u’ … ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
Dangling
reference!
161. .capacity: …
.len: 10
name.data ‘R’ ‘u’ … ‘n’ ‘s’
32
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
r
Dangling
reference!
162. fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
33http://is.gd/HJyO7A
163. fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
33http://is.gd/HJyO7A
164. fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
33
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
165. fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
33
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
166. fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
33
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
167. fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
33
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
168. fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
33
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
169. fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
33
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
170. fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
33
‘l
Lifetime: span of code where reference is used.
http://is.gd/HJyO7A
171. fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
33
‘l
Lifetime: span of code where reference is used.
Scope of data being borrowed (here, `name`)
compared against
http://is.gd/HJyO7A
172. ‘s
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
33
‘l
Lifetime: span of code where reference is used.
Scope of data being borrowed (here, `name`)
compared against
http://is.gd/HJyO7A
173. ‘s
fn main() {
let r;
{
let name = format!(“…”);
r = &name;
}
println!(“{}”, r);
}
33
‘l
Lifetime: span of code where reference is used.
Scope of data being borrowed (here, `name`)
compared against
http://is.gd/HJyO7A
error: `name` does not live long enough
r = &name;
^~~~
178. 34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
Might escape
the function!
179. 34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
Might escape
the function!
error: the type `[…]` does not fulfill the required lifetime
thread::spawn(move || {
^~~~~~~~~~~~~
note: type must outlive the static lifetime
180. 34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
error: the type `[…]` does not fulfill the required lifetime
thread::spawn(move || {
^~~~~~~~~~~~~
note: type must outlive the static lifetime
181. 34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
error: the type `[…]` does not fulfill the required lifetime
thread::spawn(move || {
^~~~~~~~~~~~~
note: type must outlive the static lifetime
182. 34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
error: the type `[…]` does not fulfill the required lifetime
thread::spawn(move || {
^~~~~~~~~~~~~
note: type must outlive the static lifetime
183. 34
use std::thread;
!
fn helper(name: &String) {
thread::spawn(move || {
use(name);
});
}
`name` can only be
used within this fn
error: the type `[…]` does not fulfill the required lifetime
thread::spawn(move || {
^~~~~~~~~~~~~
note: type must outlive the static lifetime
However: see crossbeam,
simple_parallel, etc on
crates.io
184. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
185. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
186. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ … ‘n’
String
data
len
capacity
187. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ … ‘n’
String
data
len
capacity
188. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ … ‘n’
String
data
len
capacity
189. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ … ‘n’
String
data
len
capacity
data
len
190. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ … ‘n’
String
data
len
capacity
data
len
191. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ … ‘n’
String
data
len
capacity
data
len
192. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ … ‘n’
String
data
len
capacity
‘R’ ‘u’ … ‘n’
data
len
193. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
‘R’ ‘u’ … ‘n’
String
data
len
capacity
‘R’ ‘u’ … ‘n’
data
len
‘s’
194. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
String
data
len
capacity
‘R’ ‘u’ … ‘n’
data
len
‘R’ ‘u’ … ‘n’
‘s’
195. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
String
data
len
capacity
‘R’ ‘u’ … ‘n’
data
len
‘R’ ‘u’ … ‘n’
‘s’
196. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
String
data
len
capacity
‘R’ ‘u’ … ‘n’
data
len
‘R’ ‘u’ … ‘n’
‘s’
197. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
String
data
len
capacity
‘R’ ‘u’ … ‘n’
data
len
‘R’ ‘u’ … ‘n’
‘s’
Dangling
reference!
198. Dangers of mutation
35
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
String
data
len
capacity
‘R’ ‘u’ … ‘n’
data
len
‘R’ ‘u’ … ‘n’
‘s’
Dangling
reference!
199. Rust solution
36
Compile-time read-write-lock:!
!
Creating a shared reference to X “read locks” X.
- Other readers OK.
- No writers.
- Lock lasts until reference goes out of scope.
!
Creating a mutable reference to X “writes locks” X.
- No other readers or writers.
- Lock lasts until reference goes out of scope.
Never have a reader/writer at same time.
200. Dangers of mutation
37
fn main() {
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
http://is.gd/MCPVWg
201. Dangers of mutation
37
fn main() {
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
http://is.gd/MCPVWg
202. Dangers of mutation
37
fn main() {
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
Borrow “locks”
`buffer` until `slice`
goes out of scope
http://is.gd/MCPVWg
203. Dangers of mutation
37
fn main() {
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
Borrow “locks”
`buffer` until `slice`
goes out of scope
http://is.gd/MCPVWg
204. Dangers of mutation
37
fn main() {
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
Borrow “locks”
`buffer` until `slice`
goes out of scope
error: cannot borrow `buffer` as mutable
because it is also borrowed as immutable
buffer.push_str(“s”);
^~~~~~
http://is.gd/MCPVWg
205. Dangers of mutation
37
fn main() {
let mut buffer: String = format!(“Rustacean”);
let slice = &buffer[1..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
Borrow “locks”
`buffer` until `slice`
goes out of scope
error: cannot borrow `buffer` as mutable
because it is also borrowed as immutable
buffer.push_str(“s”);
^~~~~~
http://is.gd/MCPVWg
206. fn main() {
let mut buffer: String = format!(“Rustacean”);
for i in 0 .. buffer.len() {
let slice = &buffer[i..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
buffer.push_str(“s”);
}
38
207. fn main() {
let mut buffer: String = format!(“Rustacean”);
for i in 0 .. buffer.len() {
let slice = &buffer[i..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
buffer.push_str(“s”);
}
38
Borrow “locks”
`buffer` until `slice`
goes out of scope
208. fn main() {
let mut buffer: String = format!(“Rustacean”);
for i in 0 .. buffer.len() {
let slice = &buffer[i..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
buffer.push_str(“s”);
}
38
Borrow “locks”
`buffer` until `slice`
goes out of scope
209. fn main() {
let mut buffer: String = format!(“Rustacean”);
for i in 0 .. buffer.len() {
let slice = &buffer[i..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
buffer.push_str(“s”);
}
38
Borrow “locks”
`buffer` until `slice`
goes out of scope
210. fn main() {
let mut buffer: String = format!(“Rustacean”);
for i in 0 .. buffer.len() {
let slice = &buffer[i..];
buffer.push_str(“s”);
println!(“{:?}”, slice);
}
buffer.push_str(“s”);
}
38
Borrow “locks”
`buffer` until `slice`
goes out of scope
OK: `buffer` is not borrowed here
243. Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {
… // see upcoming slide
}
}
store.add_item(…); // must be let mut
store.price(…); // let OR let mut
244. Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {
… // see upcoming slide
}
}
store.add_item(…); // must be let mut
store.price(…); // let OR let mut
245. Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {
… // see upcoming slide
}
}
store.add_item(…); // must be let mut
store.price(…); // let OR let mut
itself an &mut method
246. Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {
… // see upcoming slide
}
}
store.add_item(…); // must be let mut
store.price(…); // let OR let mut
247. Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {
… // see upcoming slide
}
}
store.add_item(…); // must be let mut
store.price(…); // let OR let mut
248. Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {
… // see upcoming slide
}
}
store.add_item(…); // must be let mut
store.price(…); // let OR let mut
249. Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {
… // see upcoming slide
}
}
store.add_item(…); // must be let mut
store.price(…); // let OR let mut
250. Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {
… // see upcoming slide
}
}
store.add_item(…); // must be let mut
store.price(…); // let OR let mut
251. Methods
44
struct Store { .. }
struct Item { .. }
!
impl Store {
fn add_item(&mut self, item: Item) {
self.items.push(item);
}
!
fn price(&self, item_name: &str) -> f32 {
… // see upcoming slide
}
}
store.add_item(…); // must be let mut
store.price(…); // let OR let mut
252. Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
253. Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
254. Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
255. Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
256. Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
257. Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
258. Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
259. Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
260. Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
261. Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
262. Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
263. Methods
45
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
return Store {
name: name,
items: vec![],
};
}
}
Store::new(some_name)
264. Return is optional
46
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
Store {
name: name,
items: vec![],
}
}
}
265. Return is optional
46
struct Store { .. }
!
impl Store {
fn new(name: String) -> Store {
Store {
name: name,
items: vec![],
}
}
}
No `;` on last expression:
“return this value”
277. For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
278. For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
279. For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
280. For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
281. For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
Vec<String>
282. For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
String
Vec<String>
283. For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
284. For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Alpha”
“Beta”
“Gamma”
v: s:
285. For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Beta”
“Gamma”
v: s:
286. For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Beta”
“Gamma”
v: s:
287. For Loops
48
fn main() {
let v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
for s in v {
println!(“{:?}”, s);
}
}
http://is.gd/6kJc0O
“Gamma”
v: s:
288. For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
289. For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
290. For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
&Vec<String>
291. For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
&String
&Vec<String>
292. For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
293. For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
s:
294. For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
s:
295. For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
s:
296. For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
s:
&mut Vec<String>
&mut String
297. For Loops
49
fn main() {
let mut v = vec![format!(“Alpha”),
format!(“Beta”),
format!(“Gamma”)];
!
for s in &v {
println!(“{:?}”, s);
}
!
for s in &mut v {
s.push_str(“.”);
}
}
“Alpha”
“Beta”
“Gamma”
v:
s:
308. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
309. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
310. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
311. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
312. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
313. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
314. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
315. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
316. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
317. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
318. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
319. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
320. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
321. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
322. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
323. 54
let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
324. let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
55
325. let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
55
326. let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
55
327. let mut best = None;
let mut best_price = INFINITY;
for store in stores {
let sum = store.total_price(&shopping_list);
match sum {
Some(s) if s < best_price => {
best = Some(store.name);
best_price = s;
}
_ => { }
}
}
55
328. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
329. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
330. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
331. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
332. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
333. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
334. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
335. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
Closure
takes ownership
of variables it uses.
336. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
Closure
takes ownership
of variables it uses.
Variables used by
this closure.
337. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
Closure
takes ownership
of variables it uses.
Variables used by
this closure.
338. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
339. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
Handle to the
thread we spawned.
340. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
341. Closure body can
produce a result,
here a (String, f32).
use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
342. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
343. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
344. use std::thread;
…
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
56
347. 57
let handle = thread::spawn(…);
… // stuff in parallel
// with new thread
348. 57
let handle = thread::spawn(…);
… // stuff in parallel
// with new thread
let (name, sum) = handle.join().unwrap();
349. 57
let handle = thread::spawn(…);
… // stuff in parallel
// with new thread
let (name, sum) = handle.join().unwrap();
350. 57
let handle = thread::spawn(…);
… // stuff in parallel
// with new thread
let (name, sum) = handle.join().unwrap();
Wait for thread
to finish and
get return value.
351. 57
let handle = thread::spawn(…);
… // stuff in parallel
// with new thread
let (name, sum) = handle.join().unwrap();
Wait for thread
to finish and
get return value.
Result<(String, f32), Error>
352. 57
let handle = thread::spawn(…);
… // stuff in parallel
// with new thread
let (name, sum) = handle.join().unwrap();
Wait for thread
to finish and
get return value.
Thread may have
panicked. Propagate.
353. 57
let handle = thread::spawn(…);
… // stuff in parallel
// with new thread
let (name, sum) = handle.join().unwrap();
Wait for thread
to finish and
get return value.
Thread may have
panicked. Propagate.Result of thread.
354. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
355. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
356. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
357. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
358. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
359. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
360. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
361. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
362. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
363. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
364. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
365. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
366. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
367. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
368. 58
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
handles.push(
thread::spawn(move || {
let sum = …;
(store.name, sum)
});
}
!
for handle in handles {
let (name, sum) =
handle.join().unwrap();
// find best price
}
369. 59
use std::thread;
…
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
370. 59
use std::thread;
…
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
Variables used by
this closure.
371. 59
use std::thread;
…
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
372. 59
use std::thread;
…
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
373. 59
use std::thread;
…
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
374. 59
use std::thread;
…
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
375. 59
use std::thread;
…
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
error: capture of moved value: `shopping_list`
let sum = store.total_price(&shopping_list);
^~~~~~~~~~~~~
…
help: perhaps you meant to use `clone()`?
376. 59
use std::thread;
…
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
error: capture of moved value: `shopping_list`
let sum = store.total_price(&shopping_list);
^~~~~~~~~~~~~
…
help: perhaps you meant to use `clone()`?
377. 60
use std::thread;
…
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
378. 60
use std::thread;
…
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
379. 60
use std::thread;
…
let shopping_list = vec![…];
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
400. Arc => Immutable
62
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = …;
let arc1 = Arc::new(shopping_list);
let data = &mut arc1[0];
http://is.gd/nP3Pvb
401. Arc => Immutable
62
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = …;
let arc1 = Arc::new(shopping_list);
let data = &mut arc1[0];
http://is.gd/nP3Pvb
402. Arc => Immutable
62
use std::sync::Arc;
let shopping_list: Vec<ShoppingList> = …;
let arc1 = Arc::new(shopping_list);
let data = &mut arc1[0];
<anon>:6:21: 6:24 error: cannot borrow immutable borrowed
content as mutable
<anon>:6 let data = &mut arc[0];
^~~
http://is.gd/nP3Pvb
403. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
404. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
405. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
406. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
407. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
408. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
409. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
410. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
411. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
412. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
413. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
414. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
415. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
416. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
417. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
418. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
419. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
420. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
421. 63
use std::thread;
…
let shopping_list = Arc::new(vec![…]);
let mut handles = vec![];
for store in stores {
let shopping_list = shopping_list.clone();
let handle =
thread::spawn(move || {
let sum = store.total_price(shopping_list);
(store.name, sum)
});
handles.push(handle);
}
// exercise (in a bit): join the handles!