Rust 为什么在这个函数中移动了迭代器?
我想得到一个函数,它接受两个Rust 为什么在这个函数中移动了迭代器?,rust,iterator,ownership,Rust,Iterator,Ownership,我想得到一个函数,它接受两个迭代器和一个回调,并按如下方式处理: fn for_xy<I: Iterator<Item = usize>, F>(ix: I, iy: I, f: F) where I: Iterator<Item = usize>, F: FnMut(usize, usize) -> (), { for x in ix { for y in iy { f(x, y);
迭代器和一个回调,并按如下方式处理:
fn for_xy<I: Iterator<Item = usize>, F>(ix: I, iy: I, f: F)
where
I: Iterator<Item = usize>,
F: FnMut(usize, usize) -> (),
{
for x in ix {
for y in iy {
f(x, y);
}
}
}
fn表示_xy(ix:I,iy:I,f:f)
哪里
I:迭代器,
F:FnMut(usize,usize)->(),
{
对于ix中的x{
在iy中为y{
f(x,y);
}
}
}
但我得到了这个错误:
error[E0382]: use of moved value: `iy`
--> src/lib.rs:7:18
|
1 | fn for_xy<I: Iterator<Item = usize>, F>(ix: I, iy: I, f: F)
| -- move occurs because `iy` has type `I`, which does not implement the `Copy` trait
...
7 | for y in iy {
| ^^ `iy` moved due to this implicit call to `.into_iter()`, in previous iteration of loop
|
note: this function takes ownership of the receiver `self`, which moves `iy`
help: consider borrowing to avoid moving into the for loop
|
7 | for y in &iy {
| ^^^
help: consider further restricting this bound
|
3 | I: Iterator<Item = usize> + Copy,
| ^^^^^^
错误[E0382]:使用移动值:`iy`
-->src/lib.rs:7:18
|
1 | fn代表_xy(ix:I,iy:I,f:f)
|--发生移动是因为'iy'具有类型'I',该类型不实现'Copy'特性
...
7 |在iy中为y{
|^^^`iy`由于在循环的上一次迭代中对`.into_iter()`的隐式调用而移动
|
注意:此函数获取接收者'self'的所有权,该接收者移动'iy'`
帮助:考虑借用以避免进入for循环
|
7 |适用于y in和iy{
| ^^^
帮助:考虑进一步限制这个界限
|
3 | I:迭代器+副本,
| ^^^^^^
如何更正此程序?当您运行for
循环时,您传递的iterable参数将被“移入”for
循环;迭代完成后,迭代器将被删除。如果要使迭代器可重用,典型的方法是添加一个Clone
绑定。此外,原则上,您将遇到相同的问题(相反)使用ix
迭代器中的x
项:因为在iy
循环的每次迭代中都要重用它们,所以需要确保它们可以被克隆或复制。这一问题不会发生在可复制的usize
中,但更通用的版本需要包含Clone
或Copy
绑定在ix::Item
:
fn表示_xy(ix:X,iy:Y,f:f)
哪里
X:迭代器,
X::项:克隆,
Y:迭代器+克隆,
F:FnMut(X::Item,Y::Item)
) -> {
对于ix中的x{
对于iy.clone()中的y{
f(x.clone(),y)
}
}
}
实际上,在Rust中遇到的大多数迭代器都是廉价可克隆的。集合迭代器(如Vec::iter
,HashMap::iter
)包含对底层集合的简单引用,以及大多数迭代器适配器(map
,filter
),等等)只要所使用的迭代器也是一样,就可以廉价地克隆。迭代器只能迭代一次。您的代码多次迭代iy
,对ix
中的每个项迭代一次。我建议接受切片而不是迭代器,因为它们可以多次迭代。另一种方法可能是需要iterator
和使用iy.copied()
。如果您的迭代器是Copy,您可能可以通过要求I:Copy来解决它。您可以-许多迭代器(包括在Vec
s上迭代的迭代器)正在请求Clone
(以及在iy.Clone()
上迭代)优于Copy
,因为更多类型实现了Clone
。其中一种类型是std::ops::Range
,它似乎很可能被传递给这样的函数。