在循环的前一次迭代中多次借用
Multiple borrow in previous iteration of loop
以下是我正在处理的代码,我探索了一个带有队列的目录路径,我想将文件系统树存储在我的数据结构中(枚举 Entry
):
use failure::Error;
use std::collections::VecDeque;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
fn main() -> Result<(), Error> {
let paths = visit_dir(Path::new(".")).map_err(Error::from)?;
Ok(())
}
#[derive(Debug)]
enum Entry {
Dir(PathBuf, Vec<Entry>),
File(PathBuf),
}
impl Entry {
fn new_dir(path: &Path) -> Entry {
Entry::Dir(path.to_path_buf(), Vec::new())
}
fn new_file(path: &Path) -> Entry {
Entry::File(path.to_path_buf())
}
/// Append a new Entry to self if self is a directory.
fn push(&mut self, path: &Path) -> Option<&mut Entry> {
if let Entry::Dir(_, ref mut content) = self {
let entry = if path.is_dir() {
Entry::new_dir(path)
} else {
Entry::new_file(path)
};
content.push(entry);
return content.last_mut();
}
None
}
fn path(&self) -> &Path {
match self {
Entry::Dir(path, _) => path,
Entry::File(path) => path,
}
}
}
fn visit_dir(root: &Path) -> io::Result<Entry> {
let mut dir = Entry::new_dir(root);
let mut queue = VecDeque::new();
queue.push_back(&mut dir);
while !queue.is_empty() {
let parent = queue.pop_front().unwrap();
let path = parent.path();
if path.is_dir() {
for entry in fs::read_dir(path)? {
let entry = entry?;
let path = entry.path();
let entry = parent.push(&path).unwrap();
if path.is_dir() {
queue.push_back(entry);
}
}
}
}
Ok(dir)
}
Link 到 Playground
我得到的错误是:
error[E0499]: cannot borrow `*parent` as mutable more than once at a time
--> src/main.rs:61:29
|
61 | let entry = parent.push(&path).unwrap();
| ^^^^^^ mutable borrow starts here in previous iteration of loop
我的问题是:
- 为什么我会收到这个错误?
- 是否有解决方法?
entry
在行中可变地借用 parent
:
let entry = parent.push(&path).unwrap();
然后,你不释放entry
,因为你存储在queue
。因此,当这是循环中的第 2 次迭代时,parent
仍然是可变借用的。这样做是不安全的。
您要做的是一棵可变引用树。这在 Rust 中行不通,这通常是个坏主意。你应该修改你想要实现的方式。
以下是我正在处理的代码,我探索了一个带有队列的目录路径,我想将文件系统树存储在我的数据结构中(枚举 Entry
):
use failure::Error;
use std::collections::VecDeque;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
fn main() -> Result<(), Error> {
let paths = visit_dir(Path::new(".")).map_err(Error::from)?;
Ok(())
}
#[derive(Debug)]
enum Entry {
Dir(PathBuf, Vec<Entry>),
File(PathBuf),
}
impl Entry {
fn new_dir(path: &Path) -> Entry {
Entry::Dir(path.to_path_buf(), Vec::new())
}
fn new_file(path: &Path) -> Entry {
Entry::File(path.to_path_buf())
}
/// Append a new Entry to self if self is a directory.
fn push(&mut self, path: &Path) -> Option<&mut Entry> {
if let Entry::Dir(_, ref mut content) = self {
let entry = if path.is_dir() {
Entry::new_dir(path)
} else {
Entry::new_file(path)
};
content.push(entry);
return content.last_mut();
}
None
}
fn path(&self) -> &Path {
match self {
Entry::Dir(path, _) => path,
Entry::File(path) => path,
}
}
}
fn visit_dir(root: &Path) -> io::Result<Entry> {
let mut dir = Entry::new_dir(root);
let mut queue = VecDeque::new();
queue.push_back(&mut dir);
while !queue.is_empty() {
let parent = queue.pop_front().unwrap();
let path = parent.path();
if path.is_dir() {
for entry in fs::read_dir(path)? {
let entry = entry?;
let path = entry.path();
let entry = parent.push(&path).unwrap();
if path.is_dir() {
queue.push_back(entry);
}
}
}
}
Ok(dir)
}
Link 到 Playground
我得到的错误是:
error[E0499]: cannot borrow `*parent` as mutable more than once at a time
--> src/main.rs:61:29
|
61 | let entry = parent.push(&path).unwrap();
| ^^^^^^ mutable borrow starts here in previous iteration of loop
我的问题是:
- 为什么我会收到这个错误?
- 是否有解决方法?
entry
在行中可变地借用parent
:let entry = parent.push(&path).unwrap();
然后,你不释放
entry
,因为你存储在queue
。因此,当这是循环中的第 2 次迭代时,parent
仍然是可变借用的。这样做是不安全的。
您要做的是一棵可变引用树。这在 Rust 中行不通,这通常是个坏主意。你应该修改你想要实现的方式。