Rust 不允许我借出变量两次吗?

Won't Rust allow me to lend a variable twice?

提问人:Machinarius 提问时间:10/26/2023 更新时间:10/26/2023 访问量:64

问:

刚刚开始我学习 Rust 的旅程。

我有一小段代码:

fn main() {
  simple_logger::init_with_env().unwrap();

  let context = libusb::Context::new().unwrap();
  log::debug!("Created a USB context");
  log::trace!("Trying to find a KA3 device");

  match find_ka3(&context) {
    None => {
      log::error!("Could not find a KA3 device, nothing can be done.");
      return;
    }
    Some(ka3_info) => do_stuff(&ka3_info)
  }
}

它无法编译,并出现以下错误:

error[E0597]: `context` does not live long enough
  --> src/main.rs:22:18
   |
18 |   let context = libusb::Context::new().unwrap();
   |       ------- binding `context` declared here
...
22 |   match find_ka3(&context) {
   |         ---------^^^^^^^^-
   |         |        |
   |         |        borrowed value does not live long enough
   |         a temporary with access to the borrow is created here ...
...
29 | }
   | -
   | |
   | `context` dropped here while still borrowed
   | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Option<KA3Info<'_>>`
   |
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
   |
28 |   };
   |    +

我通过实验找到了两种修复它的方法。方式#1:

fn main() {
  simple_logger::init_with_env().unwrap();

  let context = libusb::Context::new().unwrap();
  log::debug!("Created a USB context");
  log::trace!("Trying to find a KA3 device");

  match find_ka3(&context) {
    None => {
      log::error!("Could not find a KA3 device, nothing can be done.");
      return;
    }
    Some(ka3_info) => do_stuff(&ka3_info)
  }; // This semi-colon ends the borrowing?
}

方式#2

fn main() {
  simple_logger::init_with_env().unwrap();

  let context = libusb::Context::new().unwrap();
  log::debug!("Created a USB context");
  log::trace!("Trying to find a KA3 device");

  let find_result = find_ka3(&context);
  match find_result {
    None => {
      log::error!("Could not find a KA3 device, nothing can be done.");
      return;
    }
    Some(ka3_info) => do_stuff(&ka3_info)
  }
}

虽然我很高兴我找到了一个解决方案,但我希望有人解释为什么这两个人让借款检查器满意。对于方式 #1,我不确定为什么添加分号可以解决问题,对于方式 #2,我感到困惑的是,内联调用与提供变量调用的结果有何不同。match

Rust 借用检查器

评论

1赞 Chayim Friedman 10/26/2023
什么是 ?find_ka3()

答:

2赞 Jared Smith 10/26/2023 #1

对于 #1,省略分号是表达式的隐式返回,这意味着该值可能会在函数 main 返回使用(这并不总是表示程序退出,因此编译器不能假设这样做)。因此,添加 main 会更改返回类型,并且检查器知道在 main 返回后未使用该值。像这样的东西就是为什么显式注释你的函数签名通常是个好主意。match;()

对于 #2,它更改了正在考虑的生命周期:它现在是拥有的生命周期而不是借用的生命周期:在第二个示例中,检查器知道您立即完成了find_resultcontextcontextlet find_result = find_ka3(&context);

评论

1赞 Machinarius 10/27/2023
谢谢你的简单解释,这很有意义。