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

问题描述 投票:0回答:1

刚刚开始我学习 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 borrow-checker
1个回答
0
投票

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

对于#2,它改变了正在考虑的生命周期:现在是 
owned

find_result

的生命周期,而不是 context

borrow

© www.soinside.com 2019 - 2024. All rights reserved.