Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vector 使用不可复制的移动值[E0382][E0277]_Vector_Iterator_Rust_Clone_Ownership - Fatal编程技术网

Vector 使用不可复制的移动值[E0382][E0277]

Vector 使用不可复制的移动值[E0382][E0277],vector,iterator,rust,clone,ownership,Vector,Iterator,Rust,Clone,Ownership,我有一个所有权问题,我不太明白。基本上,我尝试在我的文件系统上创建一些硬链接,并在创建后删除它们。因此,我创建了一系列整数,这些整数映射到我想要创建和销毁的实际文件名。我的天真解决方案如下所示: use std::fs; const src_file: &'static str = "a.txt"; const file_ext: &'static str = ".txt"; fn create_hardlink(dest_file: &str) { fs::

我有一个所有权问题,我不太明白。基本上,我尝试在我的文件系统上创建一些硬链接,并在创建后删除它们。因此,我创建了一系列整数,这些整数映射到我想要创建和销毁的实际文件名。我的天真解决方案如下所示:

use std::fs;

const src_file: &'static str = "a.txt";
const file_ext: &'static str = ".txt";

fn create_hardlink(dest_file: &str) {
    fs::hard_link(&src_file, &dest_file);
}

fn main() {

    let create = (0..10000).map(|x| x.to_string() + file_ext);
    let remove = (0..10000).map(|x| x.to_string() + file_ext);

    for file in create {
        create_hardlink(&file);
    }

    for file in remove {
        fs::remove_file(&file);
    }
}
但我实际上想要实现的是一个解决方案,在这个解决方案中,我不必重复我自己创建带有文件名的静态集合,并且可以在一秒钟内重复使用
文件

...

fn main() {

    let files = (0..10000).map(|x| x.to_string() + file_ext);

    for file in files {
        create_hardlink(&file);
    }

    for file in files {
        fs::remove_file(&file);
    }
}
所以当我尝试这个方法时,编译器抱怨说,
文件的第二次使用是不可能的

src/main.rs:20:17: 20:22 error: use of moved value: `files` [E0382]
src/main.rs:20     for file in files {
因为
文件
已移动到第一个for循环中:

src/main.rs:16:17: 16:22 note: `files` moved here because it has type `core::iter::Map<core::ops::Range<i32>, [closure@src/main.rs:14:36: 14:64]>`, which is non-copyable
但这并不像我期望的那样有效:

src/main.rs:16:5: 18:6 error: the trait `core::iter::Iterator` is not implemented for the type `alloc::rc::Rc<core::cell::RefCell<core::iter::Map<core::ops::Range<_>, [closure@src/main.rs:14:53: 14:81]>>>` [E0277]
src/main.rs:16     for file in files.clone() {
src/main.rs:17         create_hardlink(&file);
src/main.rs:18     }
note: in expansion of for loop expansion
src/main.rs:16:5: 18:6 note: expansion site
src/main.rs:16:5: 18:6 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:16:5: 18:6 note: `alloc::rc::Rc<core::cell::RefCell<core::iter::Map<core::ops::Range<_>, [closure@src/main.rs:14:53: 14:81]>>>` is not an iterator; maybe try calling `.iter()` or a similar method
src/main.rs:16     for file in files.clone() {
src/main.rs:17         create_hardlink(&file);
src/main.rs:18     }
note: in expansion of for loop expansion
src/main.rs:16:5: 18:6 note: expansion site
src/main.rs:16:5: 18:6 note: required by `core::iter::IntoIterator::into_iter`
src/main.rs:16     for file in files.clone() {
src/main.rs:17         create_hardlink(&file);
src/main.rs:18     }
src/main.rs:16:5:18:6错误:未为类型'alloc::rc::rc`[E0277]实现特性'core::iter::Iterator'
src/main.rs:16用于files.clone()中的文件{
src/main.rs:17创建硬链接(&file);
src/main.rs:18}
注:在循环扩展的扩展中
src/main.rs:16:5:18:6注:扩建场地
src/main.rs:16:5:18:6帮助:运行'rustc--explain E0277'查看详细说明
src/main.rs:16:5:18:6注意:`alloc::rc::rc`不是迭代器;也许可以尝试调用“.iter()”或类似的方法
src/main.rs:16用于files.clone()中的文件{
src/main.rs:17创建硬链接(&file);
src/main.rs:18}
注:在循环扩展的扩展中
src/main.rs:16:5:18:6注:扩建场地
src/main.rs:16:5:18:6注:由'core::iter::IntoIterator::intoiter'所需`
src/main.rs:16用于files.clone()中的文件{
src/main.rs:17创建硬链接(&file);
src/main.rs:18}

我能做什么?我真的必须为类型
alloc::rc::rc实现
core::iter::Iterator
,据我所知,Rust迭代器只是前向迭代器,因此只能迭代一次。您可以
将它们收集到向量中,或使用函数生成迭代器:

//第一个选项
let files:Vec=(0..10000).map(|x | x.to_string()+file_ext).collect();
对于f-in&files{…}//Borrow`files`
//第二种选择
让files=| |(0..10000).map(| x | x.to_string()+file_ext);
对于文件中的f(){…}//调用闭包以获取迭代器

这里有几个问题

第一个是电话

for f in files { ... }
将按值获取
文件
。这可以通过引用来避免:

for f in &files { ... }
因为
(&foo).into_iter()
有效地解析为
foo.iter()


第二个是
文件
必须是
mut
,如果要迭代迭代器,则引用
&mut
。如果您有一些向量,那么迭代
和my_vector
是有意义的-您可以在不修改它的情况下迭代它。但是,如果您有一个迭代器本身,那么状态将在迭代器本身中保留和更新

let mut files = (0..10000).map(|x| x.to_string() + file_ext);

for file in &mut files {
    create_hardlink(&file);
}

for file in files {
    fs::remove_file(&file);
}


第三,即使您做了这些事情,因为您使用的是单个迭代器,所以每个元素只能迭代一次!第二个循环将为空。这就是@filmor提供的解决方案的问题。

我认为第一种选择是惯用的解决方案。第二个选项将导致额外的10000个分配,因为该范围将运行两次。但是第一个选项将一次分配所有内存,这取决于文件的数量,这可能也不是很好。感谢您的解决方案和评论!创建一个宏以避免像这样的选项2的双重分配是否是一种有价值的方法<代码>宏规则!files_vec{($range:expr)=>{$range.map(|x | x.to_string()+file_ext).collect()}
这是非常不灵活的,但预编译感谢您的解释!正如你所指出的,我的代码没有迭代器更有意义,因此我接受了@filmor的答案。
let mut files = (0..10000).map(|x| x.to_string() + file_ext);

for file in &mut files {
    create_hardlink(&file);
}

for file in files {
    fs::remove_file(&file);
}