【发布时间】:2015-11-17 11:22:10
【问题描述】:
我有一个所有权问题,我不太了解。基本上我尝试在我的文件系统上创建一些硬链接,并在创建后删除它们。因此,我创建了一个整数范围,将其映射到我喜欢创建和销毁的实际文件名。我的幼稚解决方案如下所示:
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);
}
}
但我真正想要完成的是一个解决方案,我不必重复我自己来创建带有文件名的静态集合,并且可以在第二个 for 循环中重用 files:
...
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);
}
}
所以当我尝试这个时,编译器会抱怨,files 的第二次使用是不可能的,
src/main.rs:20:17: 20:22 error: use of moved value: `files` [E0382]
src/main.rs:20 for file in files {
因为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
在阅读了rustc --explain E0382的解释后,我决定将代码更改如下:
...
fn main() {
let files = Rc::new(RefCell::new((0..10000).map(|x| x.to_string() + file_ext)));
for file in files.clone() {
create_hardlink(&file);
}
for file in files.clone() {
fs::remove_file(&file);
}
}
但这对我来说并不像预期的那样工作:
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 }
我能做什么?我真的必须为alloc::rc::Rc<core::cell::RefCell<core::iter::Map<core::ops::Range<_> 类型实现core::iter::Iterator,就像rustc --explain E0277 告诉我的那样吗?希望不会……
是否有一个简单的解决方案,例如将files 静态定义为static 或const?还是我映射Range 的方法不生锈?
为什么我有一个像<core::iter::Map<core::ops::Range<_> 这样的类型而不是像<core::iter::String> 这样的类型?
我希望你能帮我解决这个问题,并向像我这样的新手启发一点 Rust 所有权原则。
【问题讨论】:
标签: vector iterator rust clone ownership