是否有一种方法来区分正常循环终止从中断终止在Rust?



常用for/elsein rust:

在Python中,我可以使用for/else来检查for循环是否在break语句结束或"正常"结束:

prod = 1
for i in range(1, 10):
prod *= i
if prod > 123:
break
else:
print("oops! loop terminated without break.")

在Rust中有类似的方法吗?这是我最接近的,但不是特别相似。

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.");
}

似乎有一个关于rust内部的讨论;然而,对未来的可能性比惯用。

在Python中,习惯代码被称为pythonic-是否有一个类似的词来表示习惯Rust代码?

从Rust 1.65开始,你可以用一个值拆分块。这样的情况甚至在RFC中被提到作为一种动机:

let value = 'found: {
for i in 1..2 {
prod *= i;
if prod > 123 {
break 'found Some(prod);
}
}
println!("oops! loop terminated without break.");
None
};

操场。

一个简单的None初始化值提供了一种相当方便的方法:

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.");
}

我不知道这有多习惯,但有时我这样写:

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.
}

也就是说,当您准备好时,可以从内部打破外部标记循环。你甚至可以用break标签值语法给它一个类型。

通常可以转换为某种迭代器模式,而不是for循环:

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}");
}
}

游乐场

我见过人们用颞区域功能,Javascript风格:

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
})();
}

你定义一个临时函数并立即调用它,这样你就可以把return放在里面。这个技巧也用于传播?的错误,而try {}语句不稳定。

这个怎么样?

let result = {
for i in 1..10 {
prod *= i;
if prod > 123 {
Ok(())
}
}
Err(())
}

最新更新