【发布时间】:2020-07-07 20:36:27
【问题描述】:
我有一个函数可以对给定Items 上的任何迭代器进行可变引用。该函数通常可以一个接一个地使用项目,但有时必须执行前瞻。像这样检索到的项目有时会被消耗,但有时必须“添加”回迭代器(例如使用 Chain),然后此函数必须在迭代器上递归。
但是,在解决 trait 要求时,执行会在运行时崩溃:
error[E0275]: overflow evaluating the requirement `std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, &mut std::iter::Chain<std::vec::IntoIter<std::string::String>, ...
最小代码是(这里的条件表示无法达到无限递归深度):
fn foo<I: Iterator<Item = String>>(it: &mut I) -> String {
if *(&1) == 1 {
String::new()
} else {
foo(&mut vec![String::new()].into_iter().chain(it))
}
}
fn main() {
let mut it = vec!["Hello".to_string(), "World!".to_string()].into_iter();
println!["{:?}", foo(&mut it)];
}
将函数更改为接受 trait 对象可以解决问题,但我并不热衷于在这种简单情况下使用动态调度。
我是否必须重构代码、使用 trait 对象,或者是否有其他解决方案可以阻止检查器无限期地递归?
我在 x86_64-apple-darwin 上使用 Rust 1.44.1,但它也在 nightly 下崩溃。
【问题讨论】:
-
您是否探索过使用
peekable来避免在您不想的情况下从迭代器中删除条目? -
另见Why do I get “overflow evaluating the requirement” when rewriting a function using Diesel's traits into a trait method?; Curiously recurring generic trait pattern: overflow evaluating the requirement; Overflow evaluating the requirement when returning a recursive iterator using impl trait; What does “Overflow evaluating the requirement” mean and how can I fix it?
标签: recursion rust iterator traits