Rust 如何知道何时停止迭代没有上限的范围?
How does Rust know when to stop iterating over a range with no upper limit?
对于 Nth Prime Rust exercise on exercism.io,我发现有些解决方案选择 filter()
超过一个没有上限的范围。
这是一个例子:
pub fn nth(n: u32) -> u32 {
let mut primes = Vec::with_capacity((n as usize) + 1);
(2..)
.filter(|candidate| {
if !primes.iter().any(|i| candidate % i == 0) {
primes.push(*candidate);
true
} else {
false
}
})
.nth(n as usize)
.unwrap()
}
我想知道在这种情况下 Rust 什么时候停止迭代范围。它是否可能迭代到类型的最大值,或者它是否可以通过检查迭代器后面的代码来确定何时可以停止迭代(例如,通过检查 .unwrap()
在示例中何时不恐慌)?
这是由于使用了Iterator::nth
。此方法将准确地调用迭代器上的 next
方法 n
次,然后停止。
Rust 中的 Iterator
s 是延迟求值的,所以如果你在有限的时间内调用 next
method on them infinitely many times. Iterator
methods like nth
and take
内部调用 next
,它们只会“走向无穷大”,因此没有问题。
但是,如果您在非终止循环中迭代 Iterator
并且 Iterator
产生一些原始数字类型,那么当您尝试迭代过去时,您最终会遇到溢出该类型可表示的最大值。示例程序:
fn main() {
for _ in (usize::MAX-1..) {
println!("counting...");
}
}
运行-时间恐慌:
thread 'main' panicked at 'attempt to add with overflow', /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/ops/arith.rs:107:1
但这并不意味着不可能永远迭代! cycle
等一些方法允许您创建一个无限重复的序列,该序列实际上将永远持续下去,直到您手动终止程序:
fn main() {
let a = [1, 2, 3];
let mut infinite_123 = a.iter().cycle();
for _ in infinite_123 {
println!("uh oh, forever loop");
}
}
对于 Nth Prime Rust exercise on exercism.io,我发现有些解决方案选择 filter()
超过一个没有上限的范围。
这是一个例子:
pub fn nth(n: u32) -> u32 {
let mut primes = Vec::with_capacity((n as usize) + 1);
(2..)
.filter(|candidate| {
if !primes.iter().any(|i| candidate % i == 0) {
primes.push(*candidate);
true
} else {
false
}
})
.nth(n as usize)
.unwrap()
}
我想知道在这种情况下 Rust 什么时候停止迭代范围。它是否可能迭代到类型的最大值,或者它是否可以通过检查迭代器后面的代码来确定何时可以停止迭代(例如,通过检查 .unwrap()
在示例中何时不恐慌)?
这是由于使用了Iterator::nth
。此方法将准确地调用迭代器上的 next
方法 n
次,然后停止。
Iterator
s 是延迟求值的,所以如果你在有限的时间内调用 next
method on them infinitely many times. Iterator
methods like nth
and take
内部调用 next
,它们只会“走向无穷大”,因此没有问题。
但是,如果您在非终止循环中迭代 Iterator
并且 Iterator
产生一些原始数字类型,那么当您尝试迭代过去时,您最终会遇到溢出该类型可表示的最大值。示例程序:
fn main() {
for _ in (usize::MAX-1..) {
println!("counting...");
}
}
运行-时间恐慌:
thread 'main' panicked at 'attempt to add with overflow', /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/ops/arith.rs:107:1
但这并不意味着不可能永远迭代! cycle
等一些方法允许您创建一个无限重复的序列,该序列实际上将永远持续下去,直到您手动终止程序:
fn main() {
let a = [1, 2, 3];
let mut infinite_123 = a.iter().cycle();
for _ in infinite_123 {
println!("uh oh, forever loop");
}
}