首页 > 解决方案 > 不能将 x 作为可变借用,因为它也作为不可变错误借用

问题描述

我有以下代码,它采用管道文本行并记录键入某些字符所需的手指运动。LogReport需要&KeyLogger存储详细信息的 s。LogReport稍后将多个详细信息打印&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 方法是什么?

标签: rust

解决方案


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

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

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

我个人会选择选项#1。


推荐阅读