in python i can use for/else
to check whether or not a for
loop terminated at a break
statement or finished 'normally':
prod = 1
for i in range(1, 10):
prod *= i
if prod > 123:
break
else:
print("oops! loop terminated without break.")
is there a simpler/more idiomatic way to do that in rust than this?
let mut prod = 1u64;
let mut found = false;
for i in 1..10 {
prod *= i;
if prod > 123 {
found = true;
break;
}
}
if !found {
println!("oops! loop terminated without break.");
}
there seems to be a discussion about this on rust internals. but that is more about future possibilities than what is idiomatic...
CodePudding user response:
A simple None
initialized value provides a reasonably convenient way to do this:
let mut prod = 1u64;
let mut value = None;
for i in 1..10 {
prod *= i;
if prod > 123 {
value = Some(prod);
break;
}
}
if value.is_none() {
println!("oops! loop terminated without break.");
}
CodePudding user response:
I don't know how idiomatic it is but sometimes I write this:
fn main() {
let mut prod = 1u64;
let value = 'found: loop {
for i in 1..2 {
prod *= i;
if prod > 123 {
break 'found Some(prod);
}
}
println!("oops! loop terminated without break.");
break 'found None;
};
//Here value is Option<u64> with the result.
}
That is, an outer labelled loop that can be broken from inside when you are ready. You can even give it a type with the break
label value` syntax.
CodePudding user response:
I have seen people use a temporal locale function, Javascript style:
fn main() {
let mut prod = 1u64;
let value = (|| {
for i in 1..10 {
prod *= i;
if prod > 123 {
return Some(prod);
}
}
println!("oops! loop terminated without break.");
None
})();
}
You define a temporary function and immediately call it, this way you can have return
inside. This trick is also used to propagate errors with ?
, while the try {}
statement is not stable.
CodePudding user response:
Usually you can translate to some iterator pattern instead of the for
loop:
fn main() {
let mut prod = 1u64;
if let Some(i) = (1..10)
.filter_map(|i| {
prod *= i;
if prod > 123 {
Some(i)
} else {
None
}
})
.next()
{
println!("item found for {i}");
}
}
CodePudding user response:
How about this?
let result = {
for i in 1..10 {
prod *= i;
if prod > 123 {
Ok(())
}
}
Err(())
}