https://www.snoyman.com/blog/2018/11/rust-crash-course-05-rule-of-three-solutions
I also blog frequently on the Yesod Web Framework blog, as well as the FP Complete blog.
See a typo? Have a suggestion? Edit this page on Github
Below are the solutions to the exercises from the last Rust Crash Course lesson, “Rule of Three - Parameters, Iterators, and Closures.”
This post is part of a series based on teaching Rust at FP Complete. If you’re reading this post outside of the blog, you can find links to all posts in the series at the top of the introduction post. You can also subscribe to the RSS feed.
fn double(x: &mut u32) {
*x *= 2;
}
fn main() {
let mut x = 5;
double(&mut x);
println!("{}", x);
}
Notice that the variable x
does not need to be mutable, since we’re only modifying the value it references.
The (IMO) straightforward solution is:
struct InfiniteUnit;
impl IntoIterator for InfiniteUnit {
type Item = ();
type IntoIter = InfiniteUnitIter;
fn into_iter(self) -> Self::IntoIter {
InfiniteUnitIter
}
}
struct InfiniteUnitIter;
impl Iterator for InfiniteUnitIter {
type Item = ();
fn next(&mut self) -> Option<()> {
Some(())
}
}
fn main() {
let mut count = 0;
for _ in InfiniteUnit {
count += 1;
println!("count == {}", count);
if count >= 5 {
break;
}
}
}
However, if you want to be a bit more clever, there’s already a function in the standard library that creates an infinite iterator, called repeat
. Using that, you can bypass the extra struct here:
struct InfiniteUnit;
impl IntoIterator for InfiniteUnit {
type Item = ();
type IntoIter = std::iter::Repeat<()>;
fn into_iter(self) -> Self::IntoIter {
std::iter::repeat(())
}
}
fn main() {
let mut count = 0;
for _ in InfiniteUnit {
count += 1;
println!("count == {}", count);
if count >= 5 {
break;
}
}
}
The closure version:
fn main() {
let msg: &str = "Hi!";
let say_hi = |msg| println!("{}", msg);
say_hi(msg);
say_hi(msg);
}
And the function version:
fn main() {
let msg: &str = "Hi!";
fn say_hi(msg: &str) {
println!("{}", msg);
}
say_hi(msg);
say_hi(msg);
}
Since say_hi
is no longer referring to any variables in the local scope, it doesn’t need to be a closure.