【问题标题】:cannot borrow x as mutable because it is also borrowed as immutable error不能借 x 为可变的,因为它也被借为不可变的错误
【发布时间】:2026-01-22 06:05:02
【问题描述】:

我有以下代码,它采用管道传输的文本行并记录键入某些字符所需的手指运动。 LogReport 采用 &KeyLoggers,其中存储了详细信息。 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 方法是什么?

【问题讨论】:

  • KeyLoggerLogReport类型从何而来,log的类型定义是什么?包括一个可重现的例子是理想的。

标签: rust


【解决方案1】:

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

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

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

我个人会选择选项 #1。

【讨论】:

    最近更新 更多