Rust 了解在迭代器上调用两次方法时如何满足借用检查器的要求吗?

Rust 了解在迭代器上调用两次方法时如何满足借用检查器的要求吗?,rust,borrow-checker,Rust,Borrow Checker,在下面的代码中,我了解到已通过调用zipped.filter完成了借用。如果我想以后再使用zipped,我不明白的是如何修复它 我是新手,所以如果代码中存在其他问题或奇怪的习惯用法误用,我也对其感兴趣,但主要是关于如何使借用在这里工作两次 代码: fn main(){ 让数据:Vec=Vec![“abc.to_string(),“def.to_string(),“bbc.to_string()]; 对于s1 in&data{ 对于s2输入和数据{ 设zipped=s2.chars().zip(s

在下面的代码中,我了解到已通过调用
zipped.filter
完成了借用。如果我想以后再使用
zipped
,我不明白的是如何修复它

我是新手,所以如果代码中存在其他问题或奇怪的习惯用法误用,我也对其感兴趣,但主要是关于如何使借用在这里工作两次

代码:

fn main(){
让数据:Vec=Vec![“abc.to_string(),“def.to_string(),“bbc.to_string()];
对于s1 in&data{
对于s2输入和数据{
设zipped=s2.chars().zip(s1.chars());
//两个字符串的差异是否只有一个字符不同?
如果压缩了.filter(|(a,b)| a!=b).count()=1{
让newStr=zipped.filter(|(a,b)| a==b).map(|(a,|)a).collect:();
println!(“没有不同字符的字符串:{}”,newStr);
}
}
}
}
错误:

error[E0382]: use of moved value: `zipped`
   --> a.rs:10:30
    |
6   |             let zipped = s2.chars().zip(s1.chars());
    |                 ------ move occurs because `zipped` has type `Zip<Chars<'_>, Chars<'_>>`, which does not implement the `Copy` trait
...
9   |             if zipped.filter(|(a,b)| a != b).count() == 1 {
    |                       ---------------------- `zipped` moved due to this method call
10  |                 let newStr = zipped.filter(|(a,b)| a == b).map(|(a,_)| a).collect::<String>();
    |                              ^^^^^^ value used here after move
    |
note: this function consumes the receiver `self` by taking ownership of it, which moves `zipped`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0382`.
错误[E0382]:使用移动值:`zipped`
-->答:10:30
|
6 |让zipped=s2.chars().zip(s1.chars());
|----发生移动是因为'zipped'的类型为'Zip>`,而该类型未实现'Copy'特性
...
9 |如果压缩。过滤器(|(a,b)| a!=b)。计数()=1{
|-------------------------`zipped`由于此方法调用而移动
10 | let newStr=zipped.filter(|(a,b)| a==b).map(|(a,|)a).collect:();
|^^^^^^移动后此处使用的值
|
注意:此函数通过获取接收者“self”的所有权来消耗接收者“self”,它移动“zipped”`
错误:由于上一个错误而中止
有关此错误的详细信息,请尝试“rustc--explain E0382”。

您可以始终
压缩的.clone()
,它克隆迭代器,以便您在第一次调用
过滤器(…).count()
时移动克隆。压缩的原始
保持不变,您将通过第二个
过滤器(…).collect()移动它

请注意,它不会克隆任何数据,因为迭代器是惰性的,复制迭代器意味着复制其逻辑(因此它复制
.chars()
.zip()
等的逻辑,这些逻辑只是一组函数指针,而不是数据)


你能解释一下你想用代码完成什么吗?代码所做的与问题无关,只要假设我想做一些迭代器操作(例如,
filter
,等等)在
zipped
两个不同的时间:-)我明白了。因此克隆迭代器的性能影响是最小的,例如,克隆的只是迭代器的状态,而不是任何数据?编译器是否会抱怨我代码中的两个调用,因为
filter
可能修改了
zipped
或其他东西?它会编译这很好,看看@Tumbleweed53
过滤器,它会消耗迭代器,并从中生成一个新的迭代器,这样你就不能再使用它了。即使它没有通过使用
by_ref
count
运行到最后,这意味着第二次使用将不会返回任何结果。@kmdreko谢谢,这是有意义的。我需要记住它是它不是集合,而是迭代器,可以向一个方向移动。
error[E0382]: use of moved value: `zipped`
   --> a.rs:10:30
    |
6   |             let zipped = s2.chars().zip(s1.chars());
    |                 ------ move occurs because `zipped` has type `Zip<Chars<'_>, Chars<'_>>`, which does not implement the `Copy` trait
...
9   |             if zipped.filter(|(a,b)| a != b).count() == 1 {
    |                       ---------------------- `zipped` moved due to this method call
10  |                 let newStr = zipped.filter(|(a,b)| a == b).map(|(a,_)| a).collect::<String>();
    |                              ^^^^^^ value used here after move
    |
note: this function consumes the receiver `self` by taking ownership of it, which moves `zipped`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0382`.
fn main() {
    let data : Vec<String> = vec!["abc".to_string(), "def".to_string(), "bbc".to_string()];

    for s1 in &data {
        for s2 in &data {
            let zipped = s2.chars().zip(s1.chars());
            
            // << THE CHANGE IS HERE
            if zipped.clone().filter(|(a,b)| a != b).count() == 1 {
                let newStr = zipped.filter(|(a,b)| a == b).map(|(a,_)| a).collect::<String>();

                println!("String without the different character: {}", newStr);
            }
        }
    }
}
String without the different character: bc
String without the different character: bc