帮我将这个基本模式翻译成Rust。 Rust编译器抱怨所有权;它无法将self
引用传递给close
方法,因为对self.files
的不可变引用仍然存在。
我感到困惑,因为HashMap::get
正在竞争,而且它不是迭代器,所以更改files
对象有什么问题?
use std::collections::HashMap;
struct File {
ino: u64
}
struct Filesystem {
files: HashMap<u64, File>
}
impl File {
fn close(&self, fs: &mut Filesystem) {
fs.files.remove(&self.ino);
}
}
impl Filesystem {
fn release(&mut self, ino: u64) {
let file = self.files.get(&ino);
if file.is_some() {
file.unwrap().close(self)
}
}
}
fn main() {
let mut fs = Filesystem { files: HashMap::new() };
fs.release(1)
}
编译器错误是
error: cannot borrow `*self` as mutable because `self.files` is also borrowed as immutable [E0502]
file.unwrap().close(self)
^~~~
note: immutable borrow occurs here
let file = self.files.get(&ino);
^~~~~~~~~~
note: immutable borrow ends here
}
^
help: run `rustc --explain E0502` to see a detailed explanation
我最终得到指针;它易于理解和快速。我没有看到RefCell
的优点,因为无论如何都会在运行时遇到错误,所以它与使用不同消息的段错误相同。
use std::collections::HashMap;
struct File {
ino: u64
}
struct Filesystem {
files: HashMap<u64, File>
}
impl File {
fn close(&self, fs: *mut Filesystem) {
unsafe { (*fs).files.remove(&self.ino); }
}
}
impl Filesystem {
fn release(&mut self, ino: u64) {
let p = self as *mut Filesystem;
let file = self.files.get(&ino);
if file.is_some() {
file.unwrap().close(p)
}
}
}
fn main() {
let mut fs = Filesystem { files: HashMap::new() };
fs.release(1)
}