我在为一个函数编写代码时遇到问题,该函数接受一个迭代器并返回迭代成对的(Option<T>, T)
迭代器
a = [1,2,3]
assert pairwise(a) == `[(None, 1), (Some(1), 2), (Some(2), 3)]
fn pairwise<I, T>(&xs: &I) -> I
where
I: Iterator<Item = T>,
{
[None].iter().chain(xs.iter().map(Some)).zip(xs.iter())
}
fn main() {
let data: Vec<i32> = vec![1, 2, 3];
let newdata: Vec<Option<i32>, i32> = pairwise(&data).collect();
println!("{:?}", newdata);
}
error[E0599]: no method named `iter` found for type `I` in the current scope
--> src/main.rs:3:28
|
3 | [None].iter().chain(xs.iter().map(Some)).zip(xs.iter())
| ^^^^
|
不确定为什么xs
不可迭代。我已经在where
条款中陈述过它了吗?
答案 0 :(得分:2)
fn pairwise<I, T>(&xs: &I) -> I
这没有意义。请参阅What is the correct way to return an Iterator?和What is the difference between `e1` and `&e2` when used as the for-loop variable?。
I: Iterator<Item = T>,
没有理由指明Item
是T
。
[None].iter()
最好使用iter::once
。
xs.iter()
标准库中没有定义iter
方法的特征。也许你的意思是IntoIterator
?
let data: Vec<i32> = vec![1, 2, 3]
没有理由在此指定类型; i32
是默认的整数类型。
Vec<Option<i32>, i32> Vec<Option<i32>, i32>> // original version
这不是Vec
的有效类型,您的原始表单甚至没有平衡符号。
毕竟,你面临艰难的选择。您的示例代码传入一个迭代器,该迭代器具有引用到切片但您已经编写了断言,以便您希望返回非引用。您还试图两次使用任意迭代器;我不能保证这样的事情是可行的。
我看到的最通用的形式是:
use std::iter;
fn pairwise<'a, I>(xs: I) -> Box<Iterator<Item = (Option<I::Item>, I::Item)> + 'a>
where
I: 'a + IntoIterator + Clone,
{
let left = iter::once(None).chain(xs.clone().into_iter().map(Some));
let right = xs.into_iter();
Box::new(left.zip(right))
}
fn main() {
let data = vec![1, 2, 3];
let newdata: Vec<_> = pairwise(&data).collect();
assert_eq!(newdata, [(None, &1), (Some(&1), &2), (Some(&2), &3)]);
let newdata: Vec<_> = pairwise(data.iter().cloned()).collect();
assert_eq!(newdata, [(None, 1), (Some(1), 2), (Some(2), 3)]);
}
另见: