I would like to kindly share with you how one can think of the for
loop described in The book
section Methods for Iterating Over Strings. And ask you if this is correct or something else is happening.
The for
loop is this:
fn main() {
let s: String = String::from("नमस्ते");
for c in s.chars() {
println!("{}", c);
}
}
This simple for loop is actually what the following code is doing:
fn main() {
let s: String = String::from("नमस्ते");
let mut i = s.chars(); // Returns an iterator
let elem: Option<char> = i.next(); // Advances the iterator and returns the next value.
if let Some(c) = elem {
// take the `char` value out of the Option
println!("{}", c);
}
let elem: Option<char> = i.next();
if let Some(c) = elem {
println!("{}", c);
}
let elem: Option<char> = i.next();
if let Some(c) = elem {
println!("{}", c);
}
let elem: Option<char> = i.next();
if let Some(c) = elem {
println!("{}", c);
}
let elem: Option<char> = i.next();
if let Some(c) = elem {
println!("{}", c);
}
let elem: Option<char> = i.next();
if let Some(c) = elem {
println!("{}", c);
}
// the iterator is ended at this point
// every time you call `next` from here on you get `None`
let elem: Option<char> = i.next();
if let None = elem {
println!("none...");
}
let elem: Option<char> = i.next();
if let None = elem {
println!("none...");
}
}
The above code of course is not good, so you can impove it with a loop
:
fn main() {
let s: String = String::from("नमस्ते");
let mut i = s.chars();
loop {
let elem: Option<char> = i.next();
if let Some(c) = elem {
println!("{}", c);
} else {
break;
}
}
}
Or use the match
expression:
fn main() {
let s: String = String::from("नमस्ते");
let mut i = s.chars();
loop {
let elem: Option<char> = i.next();
match elem {
Some(c) => println!("{}", c),
None => break,
}
}
}
Of course we must use the more ergonomic and concise first version of the code:
fn main() {
let s: String = String::from("नमस्ते");
for c in s.chars() {
println!("{}", c);
}
}