提问人:Machinarius 提问时间:10/26/2023 更新时间:10/26/2023 访问量:64
Rust 不允许我借出变量两次吗?
Won't Rust allow me to lend a variable twice?
问:
刚刚开始我学习 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
答:
2赞
Jared Smith
10/26/2023
#1
对于 #1,省略分号是表达式的隐式返回,这意味着该值可能会在函数 main 返回后使用(这并不总是表示程序退出,因此编译器不能假设这样做)。因此,添加 main 会更改返回类型,并且检查器知道在 main 返回后未使用该值。像这样的东西就是为什么显式注释你的函数签名通常是个好主意。match
;
()
对于 #2,它更改了正在考虑的生命周期:它现在是拥有的生命周期而不是借用的生命周期:在第二个示例中,检查器知道您立即完成了find_result
context
context
let find_result = find_ka3(&context);
评论
1赞
Machinarius
10/27/2023
谢谢你的简单解释,这很有意义。
评论
find_ka3()