<buttonid="sidebar-toggle"class="icon-button"type="button"title="Toggle Table of Contents"aria-label="Toggle Table of Contents"aria-controls="sidebar">
<ahref="print.html"title="Print this book"aria-label="Print this book">
<iid="print-button"class="fa fa-print"></i>
</a>
</div>
</div>
<divid="search-wrapper"class="hidden">
<formid="searchbar-outer"class="searchbar-outer">
<inputtype="search"name="search"id="searchbar"name="searchbar"placeholder="Search this book ..."aria-controls="searchresults-outer"aria-describedby="searchresults-header">
<p>Closures are like quick functions that don't need a name. Sometimes they are called lambdas. Closures are easy to find because they use <code>||</code> instead of <code>()</code>. They are very common in Rust, and once you learn to use them you will wonder how you lived without them.</p>
<p>You can bind a closure to a variable, and then it looks exactly like a function when you use it:</p>
println!("The two numbers are {} and {}.", number, other_number);
// This closure can be as long as we want, just like a function.
};
my_closure();
}
</code></pre></pre>
<p>But closures are special because they can take variables that are outside the closure even if you only write <code>||</code>. So you can do this:</p>
let my_closure = || println!("{}", number_one + number_two);
my_closure();
}
</code></pre></pre>
<p>So this prints <code>16</code>. You didn't need to put anything in <code>||</code> because it can just take <code>number_one</code> and <code>number_two</code> and add them.</p>
<p>By the way, that is where the name <strong>closure</strong> comes from, because they take variables and "enclose" them inside. And if you want to be very correct:</p>
<ul>
<li>a <code>||</code> that doesn't enclose a variable from outside is an "anonymous function". Anonymous means "doesn't have a name". It works more like a regular function.</li>
<li>a <code>||</code> that does enclose a variable from outside is a "closure". It "encloses" the variables around it to use them.</li>
</ul>
<p>But people will often call all <code>||</code> functions closures, so you don't have to worry about the name. We will just say "closure" for anything with a <code>||</code>, but remember that it can mean an "anonymous function".</p>
<p>Why is it good to know the difference? It's because an anonymous function actually makes the same machine code as a function with a name. They feel "high level", so sometimes people think that the machine code will be complicated. But the machine code that Rust makes from it is just as fast as a regular function.</p>
<p>So let's look at some more things that closures can do. You can also do this:</p>
<p>This closure takes <code>number_one</code> and <code>number_two</code>. We also gave it a new variable <code>x</code> and said that <code>x</code> is 5. Then it adds all three together to print <code>21</code>.</p>
<p>Usually you see closures in Rust inside of a method, because it is very convenient to have a closure inside. We saw closures in the last section with <code>.map()</code> and <code>.for_each()</code>. In that section we wrote <code>|x|</code> to bring in the next item in an iterator, and that was a closure.</p>
<p>Here is another example: the <code>unwrap_or</code> method that we know that you can use to give a value if <code>unwrap</code> doesn't work. Before, we wrote: <code>let fourth = my_vec.get(3).unwrap_or(&0);</code>. But there is also an <code>unwrap_or_else</code> method that has a closure inside. So you can do this:</p>
let fourth = my_vec.get(3).unwrap_or_else(|| { // try to unwrap. If it doesn't work,
if my_vec.get(0).is_some() { // see if my_vec has something at index [0]
&my_vec[0] // Give the number at index 0 if there is something
} else {
&0 // otherwise give a &0
}
});
println!("{}", fourth);
}
</code></pre></pre>
<p>Of course, a closure can be very simple. You can just write <code>let fourth = my_vec.get(3).unwrap_or_else(|| &0);</code> for example. You don't always need to use a <code>{}</code> and write complicated code just because there is a closure. As long as you put the <code>||</code> in, the compiler knows that you have put in the closure that you need.</p>
<p>The most frequent closure method is maybe <code>.map()</code>. Let's take a look at it again. Here is one way to use it:</p>
.map(|number| number * 2) // for each item, multiply by two
.collect::<Vec<i32>>(); // then make a new Vec from this
println!("{:?}", double_vec);
}
</code></pre></pre>
<p>Another good example is with <code>.for_each()</code> after <code>.enumerate()</code>. The <code>.enumerate()</code> method gives an iterator with the index number and the item. For example: <code>[10, 9, 8]</code> becomes <code>(0, 10), (1, 9), (2, 8)</code>. The type for each item here is <code>(usize, i32)</code>. So you can do this:</p>
.for_each(|(index, number)| println!("Index number {} has number {}", index, number)); // do something for each one
}
</code></pre></pre>
<p>This prints:</p>
<pre><codeclass="language-text">Index number 0 has number 10
Index number 1 has number 9
Index number 2 has number 8
</code></pre>
<p>In this case we use <code>for_each</code> instead of <code>map</code>. <code>map</code> is for <strong>doing something to</strong> each item and passing it on, and <code>for_each</code> is <strong>doing something when you see each item</strong>. Also, <code>map</code> doesn't do anything unless you use a method like <code>collect</code>.</p>
<p>Actually, this is the interesting thing about iterators. If you try to <code>map</code> without a method like <code>collect</code>, the compiler will tell you that it doesn't do anything. It won't panic, but the compiler will tell you that you didn't do anything.</p>
= note: iterators are lazy and do nothing unless consumed
</code></pre>
<p>This is a <strong>warning</strong>, so it's not an error: the program runs fine. But why doesn't num_vec do anything? We can look at the types to see.</p>
<ul>
<li><code>let num_vec = vec![10, 9, 8];</code> Right now it is a <code>Vec<i32></code>.</li>
<li><code>.iter()</code> Now it is an <code>Iter<i32></code>. So it is an iterator with items of <code>i32</code>.</li>
<li><code>.enumerate()</code> Now it is an <code>Enumerate<Iter<i32>></code>. So it is a type <code>Enumerate</code> of type <code>Iter</code> of <code>i32</code>s.</li>
<li><code>.map()</code> Now it is a type <code>Map<Enumerate<Iter<i32>>></code>. So it is a type <code>Map</code> of type <code>Enumerate</code> of type <code>Iter</code> of <code>i32</code>s.</li>
</ul>
<p>All we did was make a more and more complicated structure. So this <code>Map<Enumerate<Iter<i32>>></code> is a structure that is ready to go, but only when we tell it what to do. Rust does this because it needs to be fast. It doesn't want to do this:</p>
<ul>
<li>iterate over all the <code>i32</code>s in the Vec</li>
<li>then enumerate over all the <code>i32</code>s from the iterator</li>
<li>then map over all the enumerated <code>i32</code>s</li>
</ul>
<p>Rust only wants to do one calculation, so it creates the structure and waits. Then if we say <code>.collect::<Vec<i32>>()</code> it knows what to do, and starts moving. This is what <code>iterators are lazy and do nothing unless consumed</code> means. The iterators don't do anything until you "consume" them (use them up).</p>
<p>You can even create complicated things like <code>HashMap</code> using <code>.collect()</code>, so it is very powerful. Here is an example of how to put two vecs into a <code>HashMap</code>. First we make the two vectors, and then we will use <code>.into_iter()</code> on them to get an iterator of values. Then we use the <code>.zip()</code> method. This method takes two iterators and attaches them together, like a zipper. Finally, we use <code>.collect()</code> to make the <code>HashMap</code>.</p>
let some_numbers = vec![0, 1, 2, 3, 4, 5]; // a Vec<i32>
let some_words = vec!["zero", "one", "two", "three", "four", "five"]; // a Vec<&str>
let number_word_hashmap = some_numbers
.into_iter() // now it is an iter
.zip(some_words.into_iter()) // inside .zip() we put in the other iter. Now they are together.
.collect::<HashMap<_, _>>();
println!("For key {} we get {}.", 2, number_word_hashmap.get(&2).unwrap());
}
</code></pre></pre>
<p>This prints:</p>
<pre><codeclass="language-text">For key 2 we get two.
</code></pre>
<p>You can see that we wrote <code><HashMap<_, _>></code> because that is enough information for Rust to decide on the type <code>HashMap<i32, &str></code>. You can write <code>.collect::<HashMap<i32, &str>>();</code> if you want, or you can write it like this if you prefer:</p>
let some_numbers = vec![0, 1, 2, 3, 4, 5]; // a Vec<i32>
let some_words = vec!["zero", "one", "two", "three", "four", "five"]; // a Vec<&str>
let number_word_hashmap: HashMap<_, _> = some_numbers // Because we tell it the type here...
.into_iter()
.zip(some_words.into_iter())
.collect(); // we don't have to tell it here
}
</code></pre></pre>
<p>There is another method that is like <code>.enumerate()</code> for <code>char</code>s: <code>char_indices()</code>. (Indices means "indexes"). You use it in the same way. Let's pretend we have a big string that made of 3-digit numbers.</p>
<h3><aclass="header"href="#_-in-a-closure"id="_-in-a-closure">|_| in a closure</a></h3>
<p>Sometimes you see <code>|_|</code> in a closure. This means that the closure needs an argument (like <code>x</code>), but you don't want to use it. So <code>|_|</code> means "Okay, this closure takes an argument but I won't give it a name because I don't care about it".</p>
<p>Here is an example of an error when you don't do that:</p>
println!("{:?}", my_vec.iter().for_each(|| println!("We didn't use the variables at all"))); // ⚠️
}
</code></pre></pre>
<p>Rust says that</p>
<pre><codeclass="language-text">error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments
--> src\main.rs:28:36
|
28 | println!("{:?}", my_vec.iter().for_each(|| println!("We didn't use the variables at all")));
| ^^^^^^^^ -- takes 0 arguments
| |
| expected closure that takes 1 argument
</code></pre>
<p>The compiler actually gives you some help:</p>
<pre><codeclass="language-text">help: consider changing the closure to take and ignore the expected argument
|
28 | println!("{:?}", my_vec.iter().for_each(|_| println!("We didn't use the variables at all")));
</code></pre>
<p>This is good advice. If you change <code>||</code> to <code>|_|</code> then it will work.</p>
<h3><aclass="header"href="#helpful-methods-for-closures-and-iterators"id="helpful-methods-for-closures-and-iterators">Helpful methods for closures and iterators</a></h3>
<p>Rust becomes a very fun to language once you become comfortable with closures. With closures you can <em>chain</em> methods to each other and do a lot of things with very little code. Here are some closures and methods used with closures that we didn't see yet.</p>
<p><code>.filter()</code>: This lets you keep the items in an iterator that you want to keep. Let's filter the months of the year.</p>
.filter(|month| month.len() < 5) // We don't want months more than 5 bytes in length.
// We know that each letter is one byte so .len() is fine
.filter(|month| month.contains("u")) // Also we only like months with the letter u
.collect::<Vec<&str>>();
println!("{:?}", filtered_months);
}
</code></pre></pre>
<p>This prints <code>["June", "July"]</code>.</p>
<p><code>.filter_map()</code>. This is called <code>filter_map()</code> because it does <code>.filter()</code> and <code>.map()</code>. The closure must return an <code>Option<T></code>, and then <code>filter_map()</code> takes the value out of each <code>Option</code> if it is <code>Some</code>. So for example if you were to <code>.filter_map()</code> a <code>vec![Some(2), None, Some(3)]</code>, it would return <code>[2, 3]</code>.</p>
<p>We will write an example with a <code>Company</code> struct. Each company has a <code>name</code> so that field is <code>String</code>, but the CEO might have recently quit. So the <code>ceo</code> field is <code>Option<String></code>. We will <code>.filter_map()</code> over some companies to just keep the CEO names.</p>
<pre><preclass="playground"><codeclass="language-rust">struct Company {
<p>This prints <code>["Unknown", "Doug Suttles"]</code>.</p>
<p>Since <code>.filter_map()</code> needs an <code>Option</code>, what about <code>Result</code>? No problem: there is a method called <code>.ok()</code> that turns <code>Result</code> into <code>Option</code>. It is called <code>.ok()</code> because all it can send is the <code>Ok</code> result (the <code>Err</code> information is gone). You remember that <code>Option</code> is <code>Option<T></code> while <code>Result</code> is <code>Result<T, E></code> with information for both <code>Ok</code> and <code>Err</code>. So when you use <code>.ok()</code>, any <code>Err</code> information is lost and it becomes <code>None</code>.</p>
<p>Using <code>.parse()</code> is an easy example for this, where we try to parse some user input. <code>.parse()</code> here takes a <code>&str</code> and tries to turn it into an <code>f32</code>. It returns a <code>Result</code>, but we are using <code>filter_map()</code> so we just throw out the errors. Anything that is <code>Err</code> becomes <code>None</code> and is filtered out by <code>.filter_map()</code>.</p>
<p>On the opposite side of <code>.ok()</code> is <code>.ok_or()</code> and <code>ok_or_else()</code>. This turns an <code>Option</code> into a <code>Result</code>. It is called <code>.ok_or()</code> because a <code>Result</code> gives an <code>Ok</code><strong>or</strong> an <code>Err</code>, so you have to let it know what the <code>Err</code> value will be. That is because <code>None</code> in an <code>Option</code> doesn't have any information. Also, you can see now that the <em>else</em> part in the names of these methods means that it has a closure.</p>
<p>We can take our <code>Option</code> from the <code>Company</code> struct and turn it into a <code>Result</code> this way. For long-term error handling it is good to create your own type of error. But for now we just give it an error message, so it becomes a <code>Result<String, &str></code>.</p>
<pre><preclass="playground"><codeclass="language-rust">// Everything before main() is exactly the same
.for_each(|company| results_vec.push(company.get_ceo().ok_or("No CEO found")));
<spanclass="boring">}
</span></code></pre></pre>
<p>It means: "For each company, use <code>get_ceo()</code>. If you get it, then pass on the value inside <code>Ok</code>. And if you don't, pass on "No CEO found" inside <code>Err</code>. Then push this into the vec."</p>
<p>So when we print <code>results_vec</code> we get this:</p>
<p>So now we have all four entries. Now let's use <code>.ok_or_else()</code> so we can use a closure and get a better error message. Now we have space to use <code>format!</code> to create a <code>String</code>, and put the company name in that. Then we return the <code>String</code>.</p>
<pre><preclass="playground"><codeclass="language-rust">// Everything before main() is exactly the same
Err("No CEO found for The Red-Headed League")
Err("No CEO found for Stark Enterprises")
</code></pre>
<p><code>.and_then()</code> is a helpful message that takes an <code>Option</code>, then lets you do something to its value and pass it on. So its input is an <code>Option</code>, and its output is also an <code>Option</code>. It is sort of like a safe "unwrap, then do something, then wrap again".</p>
<p>An easy example is a number that we get from a vec using <code>.get()</code>, because that returns an <code>Option</code>. Now we can pass it to <code>and_then()</code>, and do some math on it if it is <code>Some</code>. If it is <code>None</code>, then the <code>None</code> just gets passed through.</p>
let new_vec = vec![8, 9, 0]; // just a vec with numbers
let number_to_add = 5; // use this in the math later
let mut empty_vec = vec![]; // results go in here
for index in 0..5 {
empty_vec.push(
new_vec
.get(index)
.and_then(|number| Some(number + 1))
.and_then(|number| Some(number + number_to_add))
);
}
println!("{:?}", empty_vec);
}
</code></pre></pre>
<p>This prints <code>[Some(14), Some(15), Some(6), None, None]</code>. You can see that <code>None</code> isn't filtered out, just passed on.</p>
<p><code>.and()</code> is sort of like a <code>bool</code> for <code>Option</code>. You can match many <code>Option</code>s to each other, and if they are all <code>Some</code> then it will give the last one. And if one of them is a <code>None</code>, then it will give <code>None</code>.</p>
<p>First here is a <code>bool</code> example to help imagine. You can see that if you are using <code>&&</code> (and), even one <code>false</code> makes everything <code>false</code>.</p>
println!("{}", one && three); // prints true
println!("{}", one && two && three && four); // prints false
}
</code></pre></pre>
<p>Now here is the same thing with <code>.and()</code>. Imagine we did five operations and put the results in a Vec<Option<&str>>. If we get a value, we push <code>Some("success!")</code> to the vec. Then we do this two more times. After that we use <code>.and()</code> to only show the indexes that got <code>Some</code> every time.</p>
<p>The first one (index 0) is <code>None</code> because there is a <code>None</code> for index 0 in <code>second_try</code>. The second is <code>None</code> because there is a <code>None</code> in <code>first_try</code>. The next is <code>Some("success!")</code> because there is no <code>None</code> for <code>first_try</code>, <code>second try</code>, or <code>third_try</code>.</p>
<p><code>.any()</code> and <code>.all()</code> are very easy to use in iterators. They return a <code>bool</code> depending on your input. In this example we make a very large vec (about 20,000 items) with all the characters from <code>'a'</code> to <code>'働'</code>. Then we make a function to check if a character is inside it.</p>
<p>Next we make a smaller vec and ask it whether it is all alphabetic (with the <code>.is_alphabetic()</code> method). Then we ask it if all the characters are less than the Korean character <code>'행'</code>.</p>
<p>Also note that you put a reference in, because <code>.iter()</code> gives a reference and you need a <code>&</code> to compare with another <code>&</code>.</p>
println!("All less than the character 행? {}", smaller_vec.iter().all(|&x| x < '행'));
}
</code></pre></pre>
<p>This prints:</p>
<pre><codeclass="language-text">Is i inside? true
Is 뷁 inside? false
Is 鑿 inside? false
All alphabetic? false
All less than the character 행? true
</code></pre>
<p>By the way, <code>.any()</code> only checks until it finds one matching item, and then it stops. It won't check them all if it has already found a match. If you are going to use <code>.any()</code> on a <code>Vec</code>, it might be a good idea to push the items that might match near the front. Or you can use <code>.rev()</code> after <code>.iter()</code> to reverse the iterator. Here's one vec like that:</p>
<p>So this <code>Vec</code> has 1000 <code>6</code> followed by one <code>5</code>. Let's pretend that we want to use <code>.any()</code> to see if it contains 5. First let's make sure that <code>.rev()</code> is working. Remember, an <code>Iterator</code> always has <code>.next()</code> that lets you check what it does every time.</p>
println!("{:?}", big_vec.iter().rev().any(|&number| number == 5));
}
</code></pre></pre>
<p>And because it's <code>.rev()</code>, it only calls <code>.next()</code> one time and stops. If we don't use <code>.rev()</code> then it will call <code>.next()</code> 1001 times before it stops. This code shows it:</p>
let mut big_iter = big_vec.into_iter(); // Make it an Iterator
loop {
counter +=1;
if big_iter.next() == Some(5) { // Keep calling .next() until we get Some(5)
break;
}
}
println!("Final counter is: {}", counter);
}
</code></pre></pre>
<p>This prints <code>Final counter is: 1001</code> so we know that it had to call <code>.next()</code> 1001 times before it found 5.</p>
<p><code>.find()</code> tells you if an iterator has something, and <code>.position()</code> tells you where it is. <code>.find()</code> is different from <code>.any()</code> because it returns an <code>Option</code> with the value inside (or <code>None</code>). Meanwhile, <code>.position()</code> is also an <code>Option</code> with the position number, or <code>None</code>. In other words:</p>
<ul>
<li><code>.find()</code>: "I'll try to get it for you"</li>
<li><code>.position()</code>: "I'll try to find where it is for you"</li>
println!("{:?}", num_vec.iter().find(|&number| number % 3 == 0)); // find takes a reference, so we give it &number
println!("{:?}", num_vec.iter().find(|&number| number * 2 == 30));
println!("{:?}", num_vec.iter().position(|&number| number % 3 == 0));
println!("{:?}", num_vec.iter().position(|&number| number * 2 == 30));
}
</code></pre></pre>
<p>This prints:</p>
<pre><codeclass="language-text">Some(30) // This is the number itself
None // No number inside times 2 == 30
Some(2) // This is the position
None
</code></pre>
<p>With <code>.cycle()</code> you can create an iterator that loops forever. This type of iterator works well with <code>.zip()</code> to create something new, like this example which creates a <code>Vec<(i32, &str)></code>:</p>
let even_odd = vec!["even", "odd"];
let even_odd_vec = (0..6)
.zip(even_odd.into_iter().cycle())
.collect::<Vec<(i32, &str)>>();
println!("{:?}", even_odd_vec);
}
</code></pre></pre>
<p>So even though <code>.cycle()</code> might never end, the other iterator only runs six times when zipping them together. That means that the iterator made by <code>.cycle()</code> doesn't get a <code>.next()</code> call again so it is done after six times. The output is:</p>
<p>Something similar can be done with a range that doesn't have an ending. If you write <code>0..</code> then you create a range that never stops. You can use this very easily:</p>
<p>Another popular method is called <code>.fold()</code>. This method is used a lot to add together the items in an iterator, but you can also do a lot more. It is somewhat similar to <code>.for_each()</code>. In <code>.fold()</code>, you first add a starting value (if you are adding items together, then 0), then a comma, then the closure. The closure gives you two items: the total so far, and the next item. First here is a simple example showing <code>.fold()</code> to add items together.</p>
let a_string = "I don't have any dashes in me.";
println!(
"{}",
a_string
.chars() // Now it's an iterator
.fold("-".to_string(), |mut string_so_far, next_char| { // Start with a String "-". Bring it in as mutable each time along with the next char
string_so_far.push(next_char); // Push the char on, then '-'
string_so_far.push('-');
string_so_far} // Don't forget to pass it on to the next loop
<p>There are many other convenient methods like:</p>
<ul>
<li><code>.take_while()</code> which takes into an iterator as long as it gets <code>true</code> (<code>take while x > 5</code> for example)</li>
<li><code>.cloned()</code> which makes a clone inside the iterator. This turns a reference into a value.</li>
<li><code>.by_ref()</code> which makes an iterator take a reference. This is good to make sure that you can use a <code>Vec</code> or something similar after you use it to make an iterator.</li>
<li>Many other <code>_while</code> methods: <code>.skip_while()</code>, <code>.map_while()</code>, and so on</li>
<li><code>.sum()</code>: just adds everything together.</li>
</ul>
<p><code>.chunks()</code> and <code>.windows()</code> are two ways of cutting up a vector into a size you want. You put the size you want into the brackets. Let's say you have a vector with 10 items, and you want a size of 3. It will work like this:</p>
<ul>
<li>
<p><code>.chunks()</code> will give you four slices: [0, 1, 2], then [3, 4, 5], then [6, 7, 8], and finally [9]. So it will try to make a slice of three items, but if it doesn't have three then it won't panic. It will just give you what is left.</p>
</li>
<li>
<p><code>.windows()</code> will first give you a slice of [0, 1, 2]. Then it will move over one and give you [1, 2, 3]. It will do that until it finally reaches the last slice of three and stop.</p>
</li>
</ul>
<p>So let's use them on a simple vector of numbers. It looks like this:</p>
<p>By the way, <code>.chunks()</code> will panic if you give it nothing. You can write <code>.chunks(1000)</code> for a vector with one item, but you can't write <code>.chunks()</code> with anything with a length of 0. You can see that right in the function if you click on [src] because it says <code>assert!(chunk_size != 0);</code>.</p>
<p><code>.match_indices()</code> lets you pull out everything inside a <code>String</code> or <code>&str</code> that matches your input, and gives you the index too. It is similar to <code>.enumerate()</code> because it returns a tuple with two items.</p>
let rules = "Rule number 1: No fighting. Rule number 2: Go to bed at 8 pm. Rule number 3: Wake up at 6 am.";
let rule_locations = rules.match_indices("Rule").collect::<Vec<(_, _)>>(); // This is Vec<usize, &str> but we just tell Rust to do it
<p><code>.peekable()</code> lets you make an iterator where you can see (peek at) the next item. It's like calling <code>.next()</code> (it gives an <code>Option</code>) except that the iterator doesn't move, so you can use it as many times as you want. You can actually think of peekable as "stoppable", because you can stop for as long as you want. Here is an example of us using <code>.peek()</code> three times for every item. We can use <code>.peek()</code> forever until we use <code>.next()</code> to move to the next item.</p>
<p>Finally, here is an example where we also use <code>.match_indices()</code>. In this example we put names into a <code>struct</code> depending on the number of spaces in the <code>&str</code>.</p>