不能借 x 作为可变,因为它也被借为不可变错误

时间:2021-05-27 23:06:54

标签: rust

我有以下代码,它采用管道文本行并记录键入某些字符所需的手指移动。 LogReport 需要存储详细信息的 &KeyLoggerLogReport 稍后将来自多个 &KeyLogger 的详细信息打印为目录。

let keyboard = KeyboardBuilder::build(...);
let mut key_logger: KeyLogger = KeyLogger::new(keyboard);
let mut report = LogReport::new();

report.add_logger(String::from("QWERTY"), &key_logger);

loop {
  let mut input = String::new();

  match io::stdin().read_line(&mut input) {
    Ok(len) => {
      if len == 0 {
        return;
      } else {
        input.chars().for_each(|char| key_logger.log(&char));
        report.print();
      }
    }

    Err(error) => {
      eprintln!("error: {}", error);
      return;
    }
  }
}

编译错误很清楚,可以理解问题,但如何解决问题?我想我将不得不找到一种解决方案,仅在记录管道文本后才打印报告,但无论如何问题仍然存在。

error[E0502]: cannot borrow `key_logger` as mutable because it is also borrowed as immutable
  --> src/main.rs:25:44
   |
15 |     report.add_logger(String::from("QWERTY"), &key_logger);
   |                                               ----------- immutable borrow occurs here
...
25 |                     input.chars().for_each(|char| key_logger.log(&char));
   |                                            ^^^^^^ ---------- second borrow occurs due to use of `key_logger` in closure
   |                                            |
   |                                            mutable borrow occurs here
26 |                     report.print();
   |                     ------ immutable borrow later used here

即使第一个不可变的借用变为可变的,编译器仍然会抱怨 cannot borrow key_logger as mutable more than once at a time。 Rust 处理这种情况的方法是什么?

1 个答案:

答案 0 :(得分:1)

正如您所指出的,由于 Rust 的所有权规则,您不能在以后的可变借用之前借用键盘记录器作为不可变的可变的。

如果您必须在以后使用 LogReport 之前在它的键盘记录器中引用它,您有几个选择。

  1. 您可以将键盘记录器的所有权传递给日志报告,并从中可变地借用。
  2. 您可以使用内部可变性(Rc 和 RefCell)来共享所有权。
  3. 您可以改为为每个键盘记录器分配一个索引并将它们存储在某处,然后稍后按索引查找。
  4. unsafe 可能会起作用,但非常非常没有必要。

我个人会选择选项 #1。